diff options
Diffstat (limited to 'cpp/src/slice2cpp/Gen.cpp')
-rw-r--r-- | cpp/src/slice2cpp/Gen.cpp | 4657 |
1 files changed, 3597 insertions, 1060 deletions
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp index 05de885e742..de179f26d55 100644 --- a/cpp/src/slice2cpp/Gen.cpp +++ b/cpp/src/slice2cpp/Gen.cpp @@ -31,8 +31,58 @@ using namespace IceUtilInternal; namespace { +bool +isConstexprType(const TypePtr& type) +{ + BuiltinPtr bp = BuiltinPtr::dynamicCast(type); + if(bp) + { + switch(bp->kind()) + { + case Builtin::KindByte: + case Builtin::KindBool: + case Builtin::KindShort: + case Builtin::KindInt: + case Builtin::KindLong: + case Builtin::KindFloat: + case Builtin::KindDouble: + case Builtin::KindValue: + case Builtin::KindObject: + case Builtin::KindObjectProxy: + { + return true; + } + default: + { + return false; + } + } + } + else if(EnumPtr::dynamicCast(type) || ProxyPtr::dynamicCast(type) || ClassDeclPtr::dynamicCast(type)) + { + return true; + } + else + { + StructPtr s = StructPtr::dynamicCast(type); + if(s) + { + DataMemberList members = s->dataMembers(); + for(DataMemberList::const_iterator i = members.begin(); i != members.end(); ++i) + { + if(!isConstexprType((*i)->type())) + { + return false; + } + } + return true; + } + return false; + } +} + string -u32CodePoint(unsigned int value) +u32CodePoint(unsigned int value, bool cpp11) { ostringstream s; // @@ -40,7 +90,7 @@ u32CodePoint(unsigned int value) // With VC++ < 140 characters in the range of 0 to 0x9f cannot be represented // with a universal character name (UCN). // - if(value <= 0x9f) + if(!cpp11 && value <= 0x9f) { switch(value) { @@ -80,7 +130,7 @@ u32CodePoint(unsigned int value) } void -writeU8Buffer(const vector<unsigned char>& u8buffer, ::IceUtilInternal::Output& out) +writeU8Buffer(const vector<unsigned char>& u8buffer, ::IceUtilInternal::Output& out, bool cpp11) { vector<unsigned int> u32buffer; IceUtilInternal::ConversionResult result = convertUTF8ToUTF32(u8buffer, u32buffer, IceUtil::lenientConversion); @@ -101,7 +151,7 @@ writeU8Buffer(const vector<unsigned char>& u8buffer, ::IceUtilInternal::Output& for(vector<unsigned int>::const_iterator c = u32buffer.begin(); c != u32buffer.end(); ++c) { - out << u32CodePoint(*c); + out << u32CodePoint(*c, cpp11); } } @@ -124,7 +174,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) @@ -145,21 +195,21 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt "0123456789" "_{}[]#()<>%:;.?*+-/^&|~!=,\\\"' "; static const set<char> charSet(basicSourceChars.begin(), basicSourceChars.end()); - - if((useWstring & TypeContextUseWstring) || findMetaData(metaData) == "wstring") + bool wide = (useWstring & TypeContextUseWstring) || findMetaData(metaData) == "wstring"; + if(wide || cpp11) { // - // Wide strings + // Wide strings or C++11 narrow string // vector<unsigned char> u8buffer; // Buffer to convert multibyte characters - out << "L\""; + out << (wide ? "L\"" : "u8\""); for(size_t i = 0; i < value.size();) { if(charSet.find(value[i]) == charSet.end()) { if(static_cast<unsigned char>(value[i]) < 128) // Single byte character { - out << u32CodePoint(static_cast<unsigned char>(value[i])); + out << u32CodePoint(static_cast<unsigned char>(value[i]), cpp11); } else { @@ -173,7 +223,7 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt // if(!u8buffer.empty()) { - writeU8Buffer(u8buffer, out); + writeU8Buffer(u8buffer, out, cpp11); u8buffer.clear(); } @@ -211,7 +261,7 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt assert(codepoint.size() == sz); IceUtil::Int64 v = IceUtilInternal::strToInt64(codepoint.c_str(), 0, 16); - out << u32CodePoint(static_cast<unsigned int>(v)); + out << u32CodePoint(static_cast<unsigned int>(v), cpp11); i = j + 1 + sz; } @@ -240,12 +290,12 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt // if(!u8buffer.empty()) { - writeU8Buffer(u8buffer, out); + writeU8Buffer(u8buffer, out, cpp11); u8buffer.clear(); } out << "\""; } - else // narrow strings + else // C++98 narrow strings { out << "\""; // Opening " @@ -357,7 +407,14 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt } else if(bp && bp->kind() == Builtin::KindLong) { - out << "ICE_INT64(" << value << ")"; + if(cpp11) + { + out << value << "LL"; + } + else + { + out << "ICE_INT64(" << value << ")"; + } } else if(bp && bp->kind() == Builtin::KindFloat) { @@ -373,7 +430,24 @@ writeConstantValue(IceUtilInternal::Output& out, const TypePtr& type, const Synt EnumPtr ep = EnumPtr::dynamicCast(type); if(ep) { - out << fixKwd(value); + bool unscoped = findMetaData(ep->getMetaData()) == "%unscoped"; + if(!cpp11 || unscoped) + { + out << fixKwd(value); + } + else + { + string v = value; + string scope; + size_t pos = value.rfind("::"); + if(pos != string::npos) + { + v = value.substr(pos + 2); + scope = value.substr(0, value.size() - v.size()); + } + + out << fixKwd(scope + ep->name() + "::" + v); + } } else { @@ -415,7 +489,7 @@ writeMarshalUnmarshalDataMembers(IceUtilInternal::Output& C, } 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) @@ -434,7 +508,7 @@ 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 << ')'; } } @@ -445,7 +519,7 @@ writeDataMemberInitializers(IceUtilInternal::Output& C, const DataMemberList& me 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), @@ -455,9 +529,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) @@ -478,7 +552,7 @@ Slice::Gen::~Gen() H << "\n#endif\n"; C << '\n'; - if(_impl) + if(_implCpp98 || _implCpp11) { implH << "\n\n#endif\n"; implC << '\n'; @@ -486,6 +560,38 @@ Slice::Gen::~Gen() } void +Slice::Gen::generateChecksumMap(const UnitPtr& p) +{ + if(_checksum) + { + ChecksumMap map = createChecksums(p); + if(!map.empty()) + { + C << sp << nl << "namespace"; + C << nl << "{"; + C << sp << nl << "const char* __sliceChecksums[] ="; + C << sb; + for(ChecksumMap::const_iterator q = map.begin(); q != map.end(); ++q) + { + C << nl << "\"" << q->first << "\", \""; + ostringstream str; + str.flags(ios_base::hex); + str.fill('0'); + for(vector<unsigned char>::const_iterator r = q->second.begin(); r != q->second.end(); ++r) + { + str << static_cast<int>(*r); + } + C << str.str() << "\","; + } + C << nl << "0"; + C << eb << ';'; + C << nl << "const IceInternal::SliceChecksumInit __sliceChecksumInit(__sliceChecksums);"; + C << sp << nl << "}"; + } + } +} + +void Slice::Gen::generate(const UnitPtr& p) { string file = p->topLevelFile(); @@ -499,7 +605,7 @@ Slice::Gen::generate(const UnitPtr& p) _headerExtension = headerExtension; } - if(_impl) + if(_implCpp98 || _implCpp11) { string fileImplH = _base + "I." + _implHeaderExtension; string fileImplC = _base + "I." + _sourceExtension; @@ -541,7 +647,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; @@ -584,7 +690,7 @@ Slice::Gen::generate(const UnitPtr& p) printGeneratedHeader(C, _base + ".ice"); - string s = fileH; + string s = _base + "." + _headerExtension;; if(_include.size()) { s = _include + '/' + s; @@ -613,10 +719,10 @@ 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>"; @@ -624,30 +730,29 @@ Slice::Gen::generate(const UnitPtr& p) 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/ValueFactory.h>"; C << "\n#include <Ice/Outgoing.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>"; } @@ -657,22 +762,13 @@ Slice::Gen::generate(const UnitPtr& p) if(p->usesNonLocals()) { - C << "\n#include <Ice/BasicStream.h>"; + C << "\n#include <Ice/InputStream.h>"; + C << "\n#include <Ice/OutputStream.h>"; } - if(_stream || p->hasNonLocalClassDefs() || p->hasNonLocalExceptions()) + if(p->hasNonLocalExceptions()) { - if(!p->hasNonLocalClassDefs()) - { - C << "\n#include <Ice/LocalException.h>"; - } - - H << "\n#include <Ice/StreamF.h>"; - - if(_stream) - { - C << "\n#include <Ice/Stream.h>"; - } + C << "\n#include <Ice/LocalException.h>"; } if(p->hasContentsWithMetaData("preserve-slice")) @@ -731,96 +827,149 @@ 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); - - TypesVisitor typesVisitor(H, C, _dllExport, _stream); - p->visit(&typesVisitor, false); + H << sp; + H.zeroIndent(); + H << nl << "#ifdef ICE_CPP11_MAPPING // C++11 mapping"; + H.restoreIndent(); - StreamVisitor streamVisitor(H, C, _dllExport); - p->visit(&streamVisitor, false); + C << sp; + C.zeroIndent(); + C << nl << "#ifdef ICE_CPP11_MAPPING // C++11 mapping"; + C.restoreIndent(); + { + 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); + Cpp11StreamVisitor streamVisitor(H, C, _dllExport); + p->visit(&streamVisitor, 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); + Cpp11ProxyVisitor proxyVisitor(H, C, _dllExport); + p->visit(&proxyVisitor, false); - ProxyVisitor proxyVisitor(H, C, _dllExport); - p->visit(&proxyVisitor, false); + Cpp11LocalObjectVisitor localObjectVisitor(H, C, _dllExport); + p->visit(&localObjectVisitor, false); - ObjectVisitor objectVisitor(H, C, _dllExport, _stream); - p->visit(&objectVisitor, false); + Cpp11InterfaceVisitor interfaceVisitor(H, C, _dllExport); + p->visit(&interfaceVisitor, 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); + Cpp11ValueVisitor valueVisitor(H, C, _dllExport); + p->visit(&valueVisitor, 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()) + 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); + + StreamVisitor streamVisitor(H, C, _dllExport); + p->visit(&streamVisitor, 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); + + // + // 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 @@ -859,8 +1008,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) { } @@ -980,7 +1129,6 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) H << nl << "virtual ~" << name << "() throw();"; H << sp; - if(!p->isLocal()) { string initName = p->flattenedScope() + p->name() + "_init"; @@ -1077,10 +1225,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(); @@ -1138,135 +1286,75 @@ 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 << 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"); + //H << nl << "using " << baseName << "::__writeImpl;"; + //H << nl << "using " << baseName << "::__readImpl;"; if(preserved && !basePreserved) { H << sp << nl << "::Ice::SlicedDataPtr __slicedData;"; - C << sp << nl << "void" << nl << scoped.substr(2) << "::__write(::IceInternal::BasicStream* __os) const"; + C << sp << nl << "void" << nl << scoped.substr(2) << "::__write(::Ice::OutputStream* __os) const"; C << sb; - C << nl << "__os->startWriteException(__slicedData);"; + C << nl << "__os->startException(__slicedData);"; C << nl << "__writeImpl(__os);"; - C << nl << "__os->endWriteException();"; + C << nl << "__os->endException();"; C << eb; - C << sp << nl << "void" << nl << scoped.substr(2) << "::__read(::IceInternal::BasicStream* __is)"; + C << sp << nl << "void" << nl << scoped.substr(2) << "::__read(::Ice::InputStream* __is)"; C << sb; - C << nl << "__is->startReadException();"; + C << nl << "__is->startException();"; C << nl << "__readImpl(__is);"; - C << nl << "__slicedData = __is->endReadException(true);"; + C << nl << "__slicedData = __is->endException(true);"; C << eb; } - C << sp << nl << "void" << nl << scoped.substr(2) << "::__writeImpl(::IceInternal::BasicStream* __os) const"; + C << sp << nl << "void" << nl << scoped.substr(2) << "::__writeImpl(::Ice::OutputStream* __os) const"; C << sb; - C << nl << "__os->startWriteSlice(\"" << p->scoped() << "\", -1, " << (!base ? "true" : "false") << ");"; + C << nl << "__os->startSlice(\"" << p->scoped() << "\", -1, " << (!base ? "true" : "false") << ");"; writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), true); - C << nl << "__os->endWriteSlice();"; + C << nl << "__os->endSlice();"; if(base) { emitUpcall(base, "::__writeImpl(__os);"); } C << eb; - C << sp << nl << "void" << nl << scoped.substr(2) << "::__readImpl(::IceInternal::BasicStream* __is)"; + C << sp << nl << "void" << nl << scoped.substr(2) << "::__readImpl(::Ice::InputStream* __is)"; C << sb; - C << nl << "__is->startReadSlice();"; + C << nl << "__is->startSlice();"; writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), false); - C << nl << "__is->endReadSlice();"; + C << nl << "__is->endSlice();"; if(base) { emitUpcall(base, "::__readImpl(__is);"); } C << eb; - - if(_stream) - { - if(preserved && !basePreserved) - { - C << sp << nl << "void" << nl << scoped.substr(2) << "::__write(const ::Ice::OutputStreamPtr& __os) const"; - C << sb; - C << nl << "__os->startException(__slicedData);"; - C << nl << "__writeImpl(__os);"; - C << nl << "__os->endException();"; - C << eb; - - C << sp << nl << "void" << nl << scoped.substr(2) << "::__read(const ::Ice::InputStreamPtr& __is)"; - C << sb; - C << nl << "__is->startException();"; - C << nl << "__readImpl(__is);"; - C << nl << "__slicedData = __is->endException(true);"; - C << eb; - } - - C << sp << nl << "void" << nl << scoped.substr(2) - << "::__writeImpl(const ::Ice::OutputStreamPtr& __os) const"; - C << sb; - C << nl << "__os->startSlice(\"" << p->scoped() << "\", -1, " << (!base ? "true" : "false") << ");"; - writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), true); - C << nl << "__os->endSlice();"; - if(base) - { - emitUpcall(base, "::__writeImpl(__os);"); - } - C << eb; - - C << sp << nl << "void" << nl << scoped.substr(2) - << "::__readImpl(const ::Ice::InputStreamPtr& __is)"; - C << sb; - C << nl << "__is->startSlice();"; - writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), false); - C << nl << "__is->endSlice();"; - if(base) - { - emitUpcall(base, "::__readImpl(__is);"); - } - C << eb; - } } H << eb << ';'; if(!p->isLocal()) { // - // We need an instance here to trigger initialization if the implementation is in a shared libarry. + // We need an instance here to trigger initialization if the implementation is in a static library. // But we do this only once per source file, because a single instance is sufficient to initialize - // all of the globals in a shared library. + // all of the globals in a compilation unit. // if(!_doneStaticSymbol) { @@ -1623,7 +1711,7 @@ Slice::Gen::ProxyDeclVisitor::visitClassDecl(const ClassDeclPtr& p) string scoped = fixKwd(p->scoped()); H << sp << nl << "class " << name << ';'; - H << nl << _dllExport << "void __read(::IceInternal::BasicStream*, ::IceInternal::ProxyHandle< ::IceProxy" + H << nl << _dllExport << "void __read(::Ice::InputStream*, ::IceInternal::ProxyHandle< ::IceProxy" << scoped << ">&);"; H << nl << _dllExport << "::IceProxy::Ice::Object* upCast(::IceProxy" << scoped << "*);"; } @@ -1692,26 +1780,49 @@ 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. + // + H << sp << nl << "class _" << _dllExport << fixKwd(p->name() + "PrxBase") << " : "; 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(); + + H << sp << nl << "virtual Object* __newInstance() const = 0;"; + H << eb << ';'; } + H << sp << nl << "class " << _dllExport << name << " : "; + H << "public virtual ::IceProxy::Ice::Proxy< ::IceProxy" << scoped << ", "; + if(bases.empty()) + { + H << "::IceProxy::Ice::Object"; + } + else if(bases.size() == 1) + { + H << "::IceProxy" << fixKwd(bases.front()->scoped()); + } + else + { + H << "_" << fixKwd(p->name() + "PrxBase"); + } + H << ">"; + H << sb; H.dec(); H << nl << "public:"; @@ -1730,11 +1841,10 @@ Slice::Gen::ProxyVisitor::visitClassDefStart(const ClassDefPtr& p) C << nl << _dllExport - << "::IceProxy::Ice::Object* ::IceProxy" << scope << "upCast(::IceProxy" << scoped - << "* p) { return p; }"; + << "::IceProxy::Ice::Object* ::IceProxy" << scope << "upCast(::IceProxy" << scoped << "* p) { return p; }"; C << sp; - C << nl << "void" << nl << "::IceProxy" << scope << "__read(::IceInternal::BasicStream* __is, " + C << nl << "void" << nl << "::IceProxy" << scope << "__read(::Ice::InputStream* __is, " << "::IceInternal::ProxyHandle< ::IceProxy" << scoped << ">& v)"; C << sb; C << nl << "::Ice::ObjectPrx proxy;"; @@ -1760,131 +1870,7 @@ 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.dec(); - H << sp << nl << "private: "; - H.inc(); - H << nl << "virtual ::IceProxy::Ice::Object* __newInstance() const;"; H << eb << ';'; C << sp; @@ -1893,12 +1879,6 @@ Slice::Gen::ProxyVisitor::visitClassDefEnd(const ClassDefPtr& p) C << nl << "return "<< scoped << "::ice_staticId();"; C << eb; - C << sp << nl << "::IceProxy::Ice::Object*"; - C << nl << "IceProxy" << scoped << "::__newInstance() const"; - C << sb; - C << nl << "return new " << name << ";"; - C << eb; - _useWstring = resetUseWstring(_useWstringHist); } @@ -2038,219 +2018,13 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) string thisPointer = fixKwd(scope.substr(0, scope.size() - 2)) + "*"; string deprecateSymbol = getDeprecateSymbol(p, cl); - H << sp << nl << deprecateSymbol << retS << ' ' << fixKwd(name) << spar << paramsDecl << epar; - H << sb; - H << nl; - 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 << eb; + H << nl << deprecateSymbol << retS << ' ' << fixKwd(name) << spar << paramsDecl + << "const ::Ice::Context& __ctx = ::Ice::noExplicitContext" << epar << ";"; H << sp << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI - << "const ::Ice::Context& __ctx" << epar; + << "const ::Ice::Context& __ctx = ::Ice::noExplicitContext" << epar; H << sb; - H << nl << "return begin_" << name << spar << argsAMI << "&__ctx" << "::IceInternal::__dummyCallback" << "0" + H << nl << "return __begin_" << name << spar << argsAMI << "__ctx" << "::IceInternal::__dummyCallback" << "0" << epar << ';'; H << eb; @@ -2258,7 +2032,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) << "const ::Ice::CallbackPtr& __del" << "const ::Ice::LocalObjectPtr& __cookie = 0" << epar; H << sb; - H << nl << "return begin_" << name << spar << argsAMI << "0" << "__del" << "__cookie" << epar << ';'; + H << nl << "return __begin_" << name << spar << argsAMI << "::Ice::noExplicitContext" << "__del" << "__cookie" << epar << ';'; H << eb; H << sp << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI @@ -2266,14 +2040,14 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) << "const ::Ice::CallbackPtr& __del" << "const ::Ice::LocalObjectPtr& __cookie = 0" << epar; H << sb; - H << nl << "return begin_" << name << spar << argsAMI << "&__ctx" << "__del" << "__cookie" << epar << ';'; + H << nl << "return __begin_" << name << spar << argsAMI << "__ctx" << "__del" << "__cookie" << epar << ';'; H << eb; H << sp << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI << "const " + delNameScoped + "Ptr& __del" << "const ::Ice::LocalObjectPtr& __cookie = 0" << epar; H << sb; - H << nl << "return begin_" << name << spar << argsAMI << "0" << "__del" << "__cookie" << epar << ';'; + H << nl << "return __begin_" << name << spar << argsAMI << "::Ice::noExplicitContext" << "__del" << "__cookie" << epar << ';'; H << eb; H << sp << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI @@ -2281,7 +2055,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) << "const " + delNameScoped + "Ptr& __del" << "const ::Ice::LocalObjectPtr& __cookie = 0" << epar; H << sb; - H << nl << "return begin_" << name << spar << argsAMI << "&__ctx" << "__del" << "__cookie" << epar << ';'; + H << nl << "return __begin_" << name << spar << argsAMI << "__ctx" << "__del" << "__cookie" << epar << ';'; H << eb; H << sp << nl << retS << " end_" << name << spar << outParamsDeclAMI @@ -2296,9 +2070,7 @@ 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 << nl << "::Ice::AsyncResultPtr __begin_" << name << spar << paramsAMI << "const ::Ice::Context&" << "const ::IceInternal::CallbackBasePtr&" << "const ::Ice::LocalObjectPtr& __cookie = 0" << epar << ';'; H << nl; @@ -2306,7 +2078,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) H << nl << "public:"; H.inc(); - C << sp << nl << retS << nl << "IceProxy" << scoped << spar << paramsDecl << "const ::Ice::Context* __ctx" << epar; + C << sp << nl << retS << nl << "IceProxy" << scoped << spar << paramsDecl << "const ::Ice::Context& __ctx" << epar; C << sb; if(p->returnsData()) { @@ -2322,7 +2094,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) { C << nl << "try"; C << sb; - C << nl<< "::IceInternal::BasicStream* __os = __og.startWriteParams(" << opFormatTypeToString(p) << ");"; + C << nl<< "::Ice::OutputStream* __os = __og.startWriteParams(" << opFormatTypeToString(p) << ");"; writeMarshalCode(C, inParams, 0, true, TypeContextInParam); if(p->sendsClasses(false)) { @@ -2393,7 +2165,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) // 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 << "::Ice::UnknownUserException __uue(__FILE__, __LINE__, __ex.ice_id());"; C << nl << "throw __uue;"; C << eb; C << eb; @@ -2401,7 +2173,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) if(ret || !outParams.empty()) { writeAllocateCode(C, ParamDeclList(), p, true, _useWstring); - C << nl << "::IceInternal::BasicStream* __is = __og.startReadParams();"; + C << nl << "::Ice::InputStream* __is = __og.startReadParams();"; writeUnmarshalCode(C, outParams, p, true); if(p->returnsClasses(false)) { @@ -2417,16 +2189,16 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) } C << eb; - C << sp << nl << "::Ice::AsyncResultPtr" << nl << "IceProxy" << scope << "begin_" << name << spar << paramsDeclAMI - << "const ::Ice::Context* __ctx" << "const ::IceInternal::CallbackBasePtr& __del" + 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 << sb; if(p->returnsData()) { C << nl << "__checkAsyncTwowayOnly(" << flatName << ");"; } - 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);"; C << nl << "try"; C << sb; C << nl << "__result->prepare(" << flatName << ", " << operationModeToString(p->sendMode()) << ", __ctx);"; @@ -2436,7 +2208,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) } else { - C << nl << "::IceInternal::BasicStream* __os = __result->startWriteParams(" << opFormatTypeToString(p) <<");"; + C << nl << "::Ice::OutputStream* __os = __result->startWriteParams(" << opFormatTypeToString(p) <<");"; writeMarshalCode(C, inParams, 0, true, TypeContextInParam); if(p->sendsClasses(false)) { @@ -2444,7 +2216,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) } C << nl << "__result->endWriteParams();"; } - C << nl << "__result->invoke();"; + C << nl << "__result->invoke(" << flatName << ");"; C << eb; C << nl << "catch(const ::Ice::Exception& __ex)"; C << sb; @@ -2453,140 +2225,6 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) C << nl << "return __result;"; C << eb; - if(p->returnsData()) - { - C << nl << nl << "#ifdef ICE_CPP11"; - - // - // COMPILERFIX VC compilers up to VC110 don't support more than 10 parameters with std::function due to - // lack of variadic templates. - // - if(outDecls.size() > 10 || (outDecls.size() > 9 && !retInS.empty())) - { - - C << nl << "#if !defined(_MSC_VER) || _MSC_VER > 1700"; - - C << nl << "//"; - C << nl << "// COMPILERFIX VC compilers up to VC110 don't support more than 10 parameters with"; - C << nl << "// std::function due to lack of variadic templates."; - C << nl << "//"; - } - - C << sp << nl << "::Ice::AsyncResultPtr" << nl - << "IceProxy" << scope << "__begin_" << name << spar << paramsDeclAMI - << "const ::Ice::Context* __ctx" << "const ::IceInternal::Function<void " << spar; - - if(!retInS.empty()) - { - C << retInS; - } - C << outDecls; - - C << epar << ">& __response, " - << "const ::IceInternal::Function<void (const ::Ice::Exception&)>& __exception, " - << "const ::IceInternal::Function<void (bool)>& __sent" << epar; - - C << sb; - C << nl << "class Cpp11CB : public ::IceInternal::Cpp11FnCallbackNC"; - C << sb; - C.dec(); - C << nl << "public:"; - C.inc(); - C << sp << nl << "Cpp11CB" << spar << "const ::std::function<void " << spar; - if(!retInS.empty()) - { - C << retInS; - } - C << outDecls; - C << epar << ">& responseFunc, " - << "const ::std::function<void (const ::Ice::Exception&)>& exceptionFunc, " - << "const ::std::function<void (bool)>& sentFunc" << epar << " :"; - C.inc(); - C << nl << "::IceInternal::Cpp11FnCallbackNC(exceptionFunc, sentFunc),"; - C << nl << "_response(responseFunc)"; - C.dec(); - C << sb; - C << nl << "CallbackBase::checkCallback(true, responseFunc || exceptionFunc != nullptr);"; - C << eb; - - // - // completed. - // - C << sp << nl << "virtual void completed(const ::Ice::AsyncResultPtr& __result) const"; - C << sb; - C << nl << clScope << clName << "Prx __proxy = " << clScope << clName - << "Prx::uncheckedCast(__result->getProxy());"; - writeAllocateCode(C, outParams, p, true, _useWstring | TypeContextInParam | TypeContextAMICallPrivateEnd); - C << nl << "try"; - C << sb; - C << nl; - if(!usePrivateEnd(p)) - { - if(ret) - { - C << retEndArg << " = "; - } - C << "__proxy->end_" << p->name() << spar << outEndArgs << "__result" << epar << ';'; - } - else - { - C << "__proxy->___end_" << p->name() << spar << outEndArgs; - if(ret) - { - C << retEndArg; - } - C << "__result" << epar << ';'; - } - writeEndCode(C, outParams, p, true); - C << eb; - C << nl << "catch(const ::Ice::Exception& ex)"; - C << sb; - C << nl << "Cpp11FnCallbackNC::exception(__result, ex);"; - C << nl << "return;"; - C << eb; - C << nl << "if(_response != nullptr)"; - C << sb; - C << nl << "_response" << spar; - if(ret) - { - C << "__ret"; - } - C << outParamNamesAMI; - C << epar << ';'; - C << eb; - C << eb; - - C.dec(); - C << nl << nl << "private:"; - C.inc(); - C << nl; - C << nl << "::std::function<void " << spar; - - if(!retInS.empty()) - { - C << retInS; - } - C << outDecls; - - C << epar << "> _response;"; - - C << eb << ';'; - - C << nl << "return begin_" << name << spar << argsAMI << "__ctx" - << "new Cpp11CB(__response, __exception, __sent)" << epar << ';'; - C << eb; - - // - // COMPILERFIX VC compilers up to VC110 don't support more than 10 parameters with std::function due to - // lack of variadic templates. - // - if(outDecls.size() > 10 || (outDecls.size() > 9 && !retInS.empty())) - { - C << nl << "#endif"; - } - C << nl << "#endif"; // ICE_CPP11 - } - C << sp << nl << retS << nl << "IceProxy" << scope << "end_" << name << spar << outParamsDeclAMI << "const ::Ice::AsyncResultPtr& __result" << epar; C << sb; @@ -2628,12 +2266,12 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) } C << nl << "catch(const ::Ice::UserException& __ex)"; C << sb; - C << nl << "throw ::Ice::UnknownUserException(__FILE__, __LINE__, __ex.ice_name());"; + C << nl << "throw ::Ice::UnknownUserException(__FILE__, __LINE__, __ex.ice_id());"; C << eb; C << eb; if(ret || !outParams.empty()) { - C << nl << "::IceInternal::BasicStream* __is = __result->__startReadParams();"; + C << nl << "::Ice::InputStream* __is = __result->__startReadParams();"; writeUnmarshalCode(C, outParams, p, true, _useWstring | TypeContextAMIEnd); if(p->returnsClasses(false)) { @@ -2691,12 +2329,13 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) } C << nl << "catch(const ::Ice::UserException& __ex)"; C << sb; - C << nl << "throw ::Ice::UnknownUserException(__FILE__, __LINE__, __ex.ice_name());"; + C << nl << "throw ::Ice::UnknownUserException(__FILE__, __LINE__, __ex.ice_id());"; C << eb; C << eb; + if(ret || !outParams.empty()) { - C << nl << "::IceInternal::BasicStream* __is = __result->__startReadParams();"; + C << nl << "::Ice::InputStream* __is = __result->__startReadParams();"; writeUnmarshalCode(C, outParams, p, true, _useWstring | TypeContextAMIPrivateEnd); if(p->returnsClasses(false)) { @@ -2751,6 +2390,7 @@ Slice::Gen::ObjectDeclVisitor::visitClassDecl(const ClassDeclPtr& p) H << nl << _dllExport << "::Ice::Object* upCast(" << scoped << "*);"; H << nl << "typedef ::IceInternal::Handle< " << scoped << "> " << p->name() << "Ptr;"; H << nl << "typedef ::IceInternal::ProxyHandle< ::IceProxy" << scoped << "> " << p->name() << "Prx;"; + H << nl << "typedef " << p->name() << "Prx " << p->name() << "PrxPtr;"; H << nl << _dllExport << "void __patch(" << p->name() << "Ptr&, const ::Ice::ObjectPtr&);"; } else @@ -2771,8 +2411,8 @@ Slice::Gen::ObjectDeclVisitor::visitOperation(const OperationPtr& p) } } -Slice::Gen::ObjectVisitor::ObjectVisitor(Output& h, Output& c, const string& dllExport, bool stream) : - H(h), C(c), _dllExport(dllExport), _stream(stream), _doneStaticSymbol(false), _useWstring(false) +Slice::Gen::ObjectVisitor::ObjectVisitor(Output& h, Output& c, const string& dllExport) : + H(h), C(c), _dllExport(dllExport), _doneStaticSymbol(false), _useWstring(false) { } @@ -2827,11 +2467,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 @@ -3063,8 +2703,6 @@ Slice::Gen::ObjectVisitor::visitClassDefStart(const ClassDefPtr& p) C << sb; if(!p->isAbstract()) { - - C << nl << "::Ice::Object* __p = new " << name << "(*this);"; C << nl << "return __p;"; } @@ -3111,10 +2749,10 @@ 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;"; + << "(const ::Ice::Current& = ::Ice::noExplicitCurrent) const;"; + H << nl << "virtual const ::std::string& ice_id(const ::Ice::Current& = ::Ice::noExplicitCurrent) const;"; H << nl << "static const ::std::string& ice_staticId();"; if(!dataMembers.empty()) @@ -3347,74 +2985,56 @@ 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*);"; + H << 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::Object"); - H << nl << "using " << baseName << "::__write;"; - H << nl << "using " << baseName << "::__read;"; - } + string baseName = base ? fixKwd(base->scoped()) : string("::Ice::Object"); + 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 << 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::Object"); - H << nl << "using " << baseName << "::__writeImpl;"; - H << nl << "using " << baseName << "::__readImpl;"; - } + string baseName = base ? fixKwd(base->scoped()) : string("::Ice::Object"); + H << nl << "using " << baseName << "::__writeImpl;"; + H << nl << "using " << baseName << "::__readImpl;"; if(preserved && !basePreserved) { C << sp; - C << nl << "void" << nl << scoped.substr(2) - << "::__write(::IceInternal::BasicStream* __os) const"; + C << nl << "void" << nl << scoped.substr(2) << "::__write(::Ice::OutputStream* __os) const"; C << sb; - C << nl << "__os->startWriteObject(__slicedData);"; + C << nl << "__os->startObject(__slicedData);"; C << nl << "__writeImpl(__os);"; - C << nl << "__os->endWriteObject();"; + C << nl << "__os->endObject();"; C << eb; C << sp; - C << nl << "void" << nl << scoped.substr(2) << "::__read(::IceInternal::BasicStream* __is)"; + C << nl << "void" << nl << scoped.substr(2) << "::__read(::Ice::InputStream* __is)"; C << sb; - C << nl << "__is->startReadObject();"; + C << nl << "__is->startObject();"; C << nl << "__readImpl(__is);"; - C << nl << "__slicedData = __is->endReadObject(true);"; + C << nl << "__slicedData = __is->endObject(true);"; C << eb; } C << sp; - C << nl << "void" << nl << scoped.substr(2) - << "::__writeImpl(::IceInternal::BasicStream* __os) const"; + C << nl << "void" << nl << scoped.substr(2) << "::__writeImpl(::Ice::OutputStream* __os) const"; C << sb; - C << nl << "__os->startWriteSlice(ice_staticId(), " << p->compactId() << (!base ? ", true" : ", false") << ");"; + C << nl << "__os->startSlice(ice_staticId(), " << p->compactId() << (!base ? ", true" : ", false") << ");"; writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), true); - C << nl << "__os->endWriteSlice();"; + C << nl << "__os->endSlice();"; if(base) { emitUpcall(base, "::__writeImpl(__os);"); @@ -3422,60 +3042,17 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p) C << eb; C << sp; - C << nl << "void" << nl << scoped.substr(2) << "::__readImpl(::IceInternal::BasicStream* __is)"; + C << nl << "void" << nl << scoped.substr(2) << "::__readImpl(::Ice::InputStream* __is)"; C << sb; - C << nl << "__is->startReadSlice();"; + C << nl << "__is->startSlice();"; writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), false); - C << nl << "__is->endReadSlice();"; + C << nl << "__is->endSlice();"; if(base) { emitUpcall(base, "::__readImpl(__is);"); } C << eb; - if(_stream) - { - if(preserved && !basePreserved) - { - C << sp << nl << "void" << nl << scoped.substr(2) << "::__write(const ::Ice::OutputStreamPtr& __os) const"; - C << sb; - C << nl << "__os->startObject(__slicedData);"; - C << nl << "__writeImpl(__os);"; - C << nl << "__os->endObject();"; - C << eb; - - C << sp << nl << "void" << nl << scoped.substr(2) << "::__read(const ::Ice::InputStreamPtr& __is)"; - C << sb; - C << nl << "__is->startObject();"; - C << nl << "__readImpl(__is);"; - C << nl << "__slicedData = __is->endObject(true);"; - C << eb; - } - - C << sp << nl << "void" << nl << scoped.substr(2) - << "::__writeImpl(const ::Ice::OutputStreamPtr& __os) const"; - C << sb; - C << nl << "__os->startSlice(ice_staticId(), " << p->compactId() << (!base ? ", true" : ", false") << ");"; - writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), true); - C << nl << "__os->endSlice();"; - if(base) - { - emitUpcall(base, "::__writeImpl(__os);"); - } - C << eb; - - C << sp << nl << "void" << nl << scoped.substr(2) << "::__readImpl(const ::Ice::InputStreamPtr& __is)"; - C << sb; - C << nl << "__is->startSlice();"; - writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), false); - C << nl << "__is->endSlice();"; - if(base) - { - emitUpcall(base, "::__readImpl(__is);"); - } - C << eb; - } - if(!p->isAbstract() || p->compactId() >= 0) { C << sp << nl << "namespace"; @@ -3484,22 +3061,22 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p) if(!p->isAbstract()) { string initName = p->flattenedScope() + p->name() + "_init"; - C << sp << nl << "const ::IceInternal::DefaultObjectFactoryInit< " << scoped << "> " + C << nl << "const ::IceInternal::DefaultValueFactoryInit< " << scoped << "> " << initName << "(\"" << p->scoped() << "\");"; } if(p->compactId() >= 0) { string initName = p->flattenedScope() + p->name() + "_compactIdInit"; - C << sp << nl << "const ::IceInternal::CompactIdInit " + C << nl << "const ::IceInternal::CompactIdInit " << initName << "(\"" << p->scoped() << "\", " << p->compactId() << ");"; } C << nl << "}"; if(!p->isAbstract()) { - C << sp << nl << "::Ice::ObjectFactoryPtr" << nl << scoped.substr(2) << "::ice_factory()"; + C << sp << nl << "::Ice::ValueFactoryPtr" << nl << scoped.substr(2) << "::ice_factory()"; C << sb; - C << nl << "return ::IceInternal::factoryTable->getObjectFactory(" << scoped << "::ice_staticId());"; + C << nl << "return ::IceInternal::factoryTable->getValueFactory(" << scoped << "::ice_staticId());"; C << eb; } } @@ -3550,13 +3127,6 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p) inProtected = true; } H << sp << nl << "virtual ~" << fixKwd(p->name()) << "() {}"; - - if(!_doneStaticSymbol) - { - H.dec(); - H << sp << nl << "friend class " << p->name() << "__staticInit;"; - H.inc(); - } } if(!p->isLocal() && preserved && !basePreserved) @@ -3576,40 +3146,11 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p) if(!p->isAbstract() && !p->isLocal() && !_doneStaticSymbol) { // - // We need an instance here to trigger initialization if the implementation is in a shared library. + // We need an instance here to trigger initialization if the implementation is in a static library. // But we do this only once per source file, because a single instance is sufficient to initialize - // all of the globals in a shared library. - // - // 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 _" << p->name() << "_init = " << p->scoped() << "::ice_factory();"; } if(p->isLocal()) @@ -3748,7 +3289,7 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p) args += ", "; } - params += "const ::Ice::Current& = ::Ice::Current())"; + params += "const ::Ice::Current& = ::Ice::noExplicitCurrent)"; paramsDecl += "const ::Ice::Current& __current)"; args += "__current)"; } @@ -3759,11 +3300,11 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p) args += ')'; } - paramsAMD += "const ::Ice::Current& = ::Ice::Current())"; + paramsAMD += "const ::Ice::Current& = ::Ice::noExplicitCurrent)"; paramsDeclAMD += "const ::Ice::Current& __current)"; argsAMD += "__current)"; - bool isConst = (p->mode() == Operation::Nonmutating) || p->hasMetaData("cpp:const"); + string isConst = ((p->mode() == Operation::Nonmutating) || p->hasMetaData("cpp:const")) ? " const" : ""; bool amd = !cl->isLocal() && (cl->hasMetaData("amd") || p->hasMetaData("amd")); string deprecateSymbol = getDeprecateSymbol(p, cl); @@ -3771,24 +3312,21 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p) H << sp; if(!amd) { - H << nl << deprecateSymbol << "virtual " << retS << ' ' << fixKwd(name) << params - << (isConst ? " const" : "") << " = 0;"; + H << nl << deprecateSymbol << "virtual " << retS << ' ' << fixKwd(name) << params << isConst << " = 0;"; } else { - H << nl << deprecateSymbol << "virtual void " << name << "_async" << paramsAMD - << (isConst ? " const" : "") << " = 0;"; + H << nl << deprecateSymbol << "virtual void " << name << "_async" << paramsAMD << isConst << " = 0;"; } if(!cl->isLocal()) { H << nl << "::Ice::DispatchStatus ___" << name - << "(::IceInternal::Incoming&, const ::Ice::Current&)" << (isConst ? " const" : "") << ';'; + << "(::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" : ""); + << "(::IceInternal::Incoming& __inS" << ", const ::Ice::Current& __current)" << isConst; C << sb; if(!amd) { @@ -3813,7 +3351,7 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p) if(!inParams.empty()) { - C << nl << "::IceInternal::BasicStream* __is = __inS.startReadParams();"; + C << nl << "::Ice::InputStream* __is = __inS.startReadParams();"; writeAllocateCode(C, inParams, 0, true, _useWstring | TypeContextInParam); writeUnmarshalCode(C, inParams, 0, true, TypeContextInParam); if(p->sendsClasses(false)) @@ -3841,7 +3379,7 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p) C << fixKwd(name) << args << ';'; if(ret || !outParams.empty()) { - C << nl << "::IceInternal::BasicStream* __os = __inS.__startWriteParams(" + C << nl << "::Ice::OutputStream* __os = __inS.__startWriteParams(" << opFormatTypeToString(p) << ");"; writeMarshalCode(C, outParams, p, true); if(p->returnsClasses(false)) @@ -3875,7 +3413,7 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p) if(!inParams.empty()) { - C << nl << "::IceInternal::BasicStream* __is = __inS.startReadParams();"; + C << nl << "::Ice::InputStream* __is = __inS.startReadParams();"; writeAllocateCode(C, inParams, 0, true, _useWstring | TypeContextInParam); writeUnmarshalCode(C, inParams, 0, true, TypeContextInParam); if(p->sendsClasses(false)) @@ -3908,7 +3446,7 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p) 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; @@ -3940,12 +3478,6 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p) } } - H << nl << "// Only supported with C++ 11 support enabled"; - H << nl << "virtual ::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI - << "const ::IceInternal::Function<void (const ::Ice::Exception&)>& exception" - << "const ::IceInternal::Function<void (bool)>& sent = ::IceInternal::Function<void (bool)>()" - << epar << " = 0;"; - H << sp << nl << "virtual ::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI << epar << " = 0;"; H << sp << nl << "virtual ::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI @@ -4045,7 +3577,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; @@ -4232,7 +3766,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; } @@ -4270,7 +3804,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; } @@ -4279,7 +3813,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;"; } @@ -4317,7 +3851,6 @@ void Slice::Gen::AsyncCallbackTemplateVisitor::visitModuleEnd(const ModulePtr&) { _useWstring = resetUseWstring(_useWstringHist); - H << sp << nl << '}'; } @@ -4591,57 +4124,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) @@ -4650,84 +4134,76 @@ Slice::Gen::ImplVisitor::writeReturn(Output& out, const TypePtr& type, const Str { case Builtin::KindBool: { - out << nl << "return false;"; - break; + return "false"; } case Builtin::KindByte: case Builtin::KindShort: case Builtin::KindInt: case Builtin::KindLong: { - out << nl << "return 0;"; - break; + return "0"; } case Builtin::KindFloat: case Builtin::KindDouble: { - out << nl << "return 0.0;"; - break; + return "0.0"; } case Builtin::KindString: { - out << nl << "return ::std::string();"; - break; + return "::std::string()"; } + case Builtin::KindValue: case Builtin::KindObject: case Builtin::KindObjectProxy: case Builtin::KindLocalObject: { - out << nl << "return 0;"; - break; + return "0"; } } } else { ProxyPtr prx = ProxyPtr::dynamicCast(type); - if(prx) + + if(ProxyPtr::dynamicCast(type) || ClassDeclPtr::dynamicCast(type)) { - out << nl << "return 0;"; + return "0"; } - else + + StructPtr st = StructPtr::dynamicCast(type); + if(st) { - ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type); - if(cl) - { - out << nl << "return 0;"; - } - else - { - StructPtr st = StructPtr::dynamicCast(type); - if(st) - { - out << nl << "return " << fixKwd(st->scoped()) << "();"; - } - else - { - EnumPtr en = EnumPtr::dynamicCast(type); - if(en) - { - EnumeratorList enumerators = en->getEnumerators(); - out << nl << "return " << fixKwd(en->scope()) << fixKwd(enumerators.front()->name()) << ';'; - } - else - { - SequencePtr seq = SequencePtr::dynamicCast(type); - if(seq) - { - out << nl << "return " << typeToString(seq, metaData, _useWstring) << "();"; - } - else - { - DictionaryPtr dict = DictionaryPtr::dynamicCast(type); - assert(dict); - out << nl << "return " << fixKwd(dict->scoped()) << "();"; - } - } - } - } + return fixKwd(st->scoped()) + "()"; + } + + EnumPtr en = EnumPtr::dynamicCast(type); + if(en) + { + EnumeratorList enumerators = en->getEnumerators(); + return fixKwd(en->scope() + enumerators.front()->name()); + } + + SequencePtr seq = SequencePtr::dynamicCast(type); + if(seq) + { + return typeToString(seq, metaData, _useWstring, true) + "()"; + } + + 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 @@ -4737,32 +4213,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; } @@ -4788,38 +4240,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); @@ -4841,10 +4280,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(); @@ -4859,7 +4295,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"; @@ -4871,22 +4307,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) { @@ -4896,7 +4321,7 @@ Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p) { C << ", "; } - C << fixKwd((*q)->name()); + C << defaultValue((*q)->type(), op->getMetaData()); } } C << ");"; @@ -4914,17 +4339,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()) { @@ -4936,9 +4358,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) << '('; @@ -4949,17 +4371,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()) { @@ -4971,7 +4392,7 @@ Slice::Gen::ImplVisitor::visitClassDefStart(const ClassDefPtr& p) } C.restoreIndent(); C << ')'; - C << (isConst ? " const" : ""); + C << isConst; C << sb; if(ret) @@ -5101,13 +4522,13 @@ Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p) } } - paramsInvoke.push_back("const ::Ice::Context*"); - paramsDeclInvoke.push_back("const ::Ice::Context* __ctx"); + paramsInvoke.push_back("const ::Ice::Context&"); + paramsDeclInvoke.push_back("const ::Ice::Context& __ctx"); if(cl->hasMetaData("amd") || p->hasMetaData("amd")) { H << sp << nl << "class " << _dllExport << classNameAMD << '_' << name - << " : virtual public ::Ice::AMDCallback"; + << " : public virtual ::Ice::AMDCallback"; H << sb; H.dec(); H << nl << "public:"; @@ -5295,7 +4716,7 @@ Slice::Gen::AsyncImplVisitor::visitOperation(const OperationPtr& p) { C << nl << "try"; C << sb; - C << nl << "::IceInternal::BasicStream* __os = __startWriteParams(" << opFormatTypeToString(p) << ");"; + C << nl << "::Ice::OutputStream* __os = __startWriteParams(" << opFormatTypeToString(p) << ");"; writeMarshalCode(C, outParams, p, false, TypeContextInParam); if(p->returnsClasses(false)) { @@ -5476,16 +4897,20 @@ Slice::Gen::StreamVisitor::visitStructStart(const StructPtr& p) // 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 << "template struct " << _dllExport << "StreamWriter< " << fullStructName + << ", ::Ice::OutputStream>;"; + H << nl << "template struct " << _dllExport << "StreamReader< " << fullStructName + << ", ::Ice::InputStream>;"; 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 << "template struct " << _dllExport << "StreamWriter< " << fullStructName + << ", ::Ice::OutputStream>;"; + C << nl << "template struct " << _dllExport << "StreamReader< " << fullStructName + << ", ::Ice::InputStream>;"; C << nl << "#endif"; } } @@ -5715,14 +5140,20 @@ void Slice::Gen::MetaDataVisitor::validate(const SyntaxTreeBasePtr& cont, const StringList& metaData, const string& file, const string& line, bool /*inParam*/) { - static const string prefix = "cpp:"; + static const string cppPrefix = "cpp:"; + static const string cpp11Prefix = "cpp11:"; + for(StringList::const_iterator p = metaData.begin(); p != metaData.end(); ++p) { string s = *p; if(_history.count(s) == 0) { - if(s.find(prefix) == 0) + bool cpp = s.find(cppPrefix) == 0; + bool cpp11 = s.find(cpp11Prefix) == 0; + if(cpp || cpp11) { + const string prefix = cpp ? cppPrefix : cpp11Prefix; + string ss = s.substr(prefix.size()); if(ss == "type:wstring" || ss == "type:string") { @@ -5758,14 +5189,41 @@ Slice::Gen::MetaDataVisitor::validate(const SyntaxTreeBasePtr& cont, const Strin { continue; } - if(ClassDefPtr::dynamicCast(cont) && ss == "virtual") + { - continue; + ClassDefPtr cl = ClassDefPtr::dynamicCast(cont); + if(cl && ((cpp && ss == "virtual") || + (cpp11 && cl->isLocal() && ss.find("type:") == 0) || + (cl->isLocal() && ss == "comparable"))) + { + continue; + } } if(ExceptionPtr::dynamicCast(cont) && ss == "ice_print") { continue; } + if(EnumPtr::dynamicCast(cont) && ss == "unscoped") + { + continue; + } + + { + ClassDeclPtr cl = ClassDeclPtr::dynamicCast(cont); + if(cl && cpp11 && cl->isLocal() && ss.find("type:") == 0) + { + continue; + } + } + emitWarning(file, line, "ignoring invalid metadata `" + s + "'"); + } + if(s.find("delegate") == 0) + { + ClassDefPtr cl = ClassDefPtr::dynamicCast(cont); + if(cl && cl->isDelegate()) + { + continue; + } emitWarning(file, line, "ignoring invalid metadata `" + s + "'"); } _history.insert(s); @@ -5811,3 +5269,3082 @@ Slice::Gen::getHeaderExt(const string& file, const UnitPtr& unit) } return ext; } + +// C++11 visitors +Slice::Gen::Cpp11DeclVisitor::Cpp11DeclVisitor(Output& h, Output& c, const string& dllExport) : + H(h), C(c), _dllExport(dllExport) +{ +} + +bool +Slice::Gen::Cpp11DeclVisitor::visitUnitStart(const UnitPtr& p) +{ + if(!p->hasClassDecls() && !p->hasNonLocalExceptions()) + { + return false; + } + C << sp << nl << "namespace" << nl << "{"; + return true; +} + +void +Slice::Gen::Cpp11DeclVisitor::visitUnitEnd(const UnitPtr& p) +{ + C << sp << nl << "}"; +} + +bool +Slice::Gen::Cpp11DeclVisitor::visitModuleStart(const ModulePtr& p) +{ + if(p->hasClassDecls()) + { + H << sp << nl << "namespace " << fixKwd(p->name()) << nl << '{' << sp; + } + return true; +} + +void +Slice::Gen::Cpp11DeclVisitor::visitModuleEnd(const ModulePtr& p) +{ + if(p->hasClassDecls()) + { + H << sp << nl << '}'; + } +} + +void +Slice::Gen::Cpp11DeclVisitor::visitClassDecl(const ClassDeclPtr& p) +{ + ClassDefPtr def = p->definition(); + if(def && def->isDelegate()) + { + return; + } + + H << nl << "class " << fixKwd(p->name()) << ';'; + if(p->isInterface() || (def && !def->allOperations().empty())) + { + H << nl << "class " << p->name() << "Prx;"; + } +} + +bool +Slice::Gen::Cpp11DeclVisitor::visitClassDefStart(const ClassDefPtr& p) +{ + if(p->isLocal()) + { + return false; + } + + if(!p->isInterface()) + { + C << sp; + + C << nl << "const ::IceInternal::DefaultValueFactoryInit<" << fixKwd(p->scoped()) << "> "; + C << p->flattenedScope() + p->name() + "_init" << "(\"" << p->scoped() << "\");"; + + if(p->compactId() >= 0) + { + string n = p->flattenedScope() + p->name() + "_compactIdInit "; + C << "const ::IceInternal::CompactIdInit " << n << "(\"" << p->scoped() << "\", " << p->compactId() << ");"; + } + } + + OperationList allOps = p->allOperations(); + if(p->isInterface() || !allOps.empty()) + { + C << sp; + + ClassList allBases = p->allBases(); + StringList ids; + transform(allBases.begin(), allBases.end(), back_inserter(ids), ::IceUtil::constMemFun(&Contained::scoped)); + StringList other; + other.push_back(p->scoped()); + other.push_back("::Ice::Object"); + other.sort(); + ids.merge(other); + ids.unique(); + + C << nl << "const ::std::string " << p->flattenedScope() << p->name() << "_ids[" << ids.size() << "] ="; + C << sb; + for(StringList::const_iterator r = ids.begin(); r != ids.end();) + { + C << nl << '"' << *r << '"'; + if(++r != ids.end()) + { + C << ','; + } + } + C << eb << ';'; + + StringList allOpNames; + transform(allOps.begin(), allOps.end(), back_inserter(allOpNames), ::IceUtil::constMemFun(&Contained::name)); + allOpNames.push_back("ice_id"); + allOpNames.push_back("ice_ids"); + allOpNames.push_back("ice_isA"); + allOpNames.push_back("ice_ping"); + allOpNames.sort(); + allOpNames.unique(); + + C << nl << "const ::std::string " << p->flattenedScope() << p->name() << "_ops[] ="; + C << sb; + for(StringList::const_iterator q = allOpNames.begin(); q != allOpNames.end();) + { + C << nl << '"' << *q << '"'; + if(++q != allOpNames.end()) + { + C << ','; + } + } + C << eb << ';'; + } + + return true; +} + +bool +Slice::Gen::Cpp11DeclVisitor::visitExceptionStart(const ExceptionPtr& p) +{ + if(p->isLocal()) + { + return false; + } + + C << sp; + C << nl << "const ::IceInternal::DefaultUserExceptionFactoryInit<" << fixKwd(p->scoped()) << "> "; + C << p->flattenedScope() + p->name() + "_init" << "(\"" << p->scoped() << "\");"; + return false; +} + +void +Slice::Gen::Cpp11DeclVisitor::visitOperation(const OperationPtr& p) +{ + ClassDefPtr cl = ClassDefPtr::dynamicCast(p->container()); + if(cl && !cl->isLocal()) + { + string flatName = p->flattenedScope() + p->name() + "_name"; + C << nl << "const ::std::string " << flatName << " = \"" << p->name() << "\";"; + } +} + +Slice::Gen::Cpp11TypesVisitor::Cpp11TypesVisitor(Output& h, Output& c, const string& dllExport) : + H(h), C(c), _dllExport(dllExport), _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&) +{ + 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, true); + allTypes.push_back(typeName); + allParamDecls.push_back(typeName + " " + fixKwd("__ice_" + (*q)->name())); + } + + if(base) + { + baseDataMembers = base->allDataMembers(); + for(DataMemberList::const_iterator q = baseDataMembers.begin(); q != baseDataMembers.end(); ++q) + { + baseParams.push_back(fixKwd("__ice_" + (*q)->name())); + } + } + + H << sp << nl << "class " << _dllExport << name << " : "; + H.useCurrentPosAsIndent(); + H << "public "; + if(!base) + { + H << (p->isLocal() ? "::Ice::LocalException" : "::Ice::UserException"); + } + else + { + H << fixKwd(base->scoped()); + } + H.restoreIndent(); + H << sb; + + H.dec(); + H << nl << "public:"; + H.inc(); + + if(p->isLocal()) + { + H << sp << nl << name << "(const char* __ice_file, int __ice_line) : "; + H << (base ? fixKwd(base->scoped()) : "::Ice::LocalException") << "(__ice_file, __ice_line)"; + H << sb; + H << eb; + } + else + { + H << sp << nl << name << "() = default;"; + } + + if(!allDataMembers.empty()) + { + H << sp << nl << name << "("; + if(p->isLocal()) + { + H << "const char* __ice_file, int __ice_line"; + if(!allParamDecls.empty()) + { + H << ", "; + } + } + + for(vector<string>::const_iterator q = allParamDecls.begin(); q != allParamDecls.end(); ++q) + { + if(q != allParamDecls.begin()) + { + H << ", "; + } + H << (*q); + } + H << ") :"; + H.inc(); + if(base && (p->isLocal() || !baseDataMembers.empty())) + { + H << nl << fixKwd(base->scoped()) << "("; + if(p->isLocal()) + { + H << "__ice_file, __ice_line"; + if(!baseDataMembers.empty()) + { + H << ", "; + } + } + + for(DataMemberList::const_iterator q = baseDataMembers.begin(); q != baseDataMembers.end(); ++q) + { + if(q != baseDataMembers.begin()) + { + H << ", "; + } + if(isMovable((*q)->type())) + { + H << "::std::move(" << fixKwd("__ice_" + (*q)->name()) << ")"; + } + else + { + H << fixKwd("__ice_" + (*q)->name()); + } + } + + H << ")"; + if(!dataMembers.empty()) + { + H << ","; + } + } + else if(p->isLocal()) + { + H << nl << "::Ice::LocalException(__ice_file, __ice_line)"; + if(!dataMembers.empty()) + { + H << ","; + } + } + + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + if(q != dataMembers.begin()) + { + H << ", "; + } + if(isMovable((*q)->type())) + { + H << nl << fixKwd((*q)->name()) << "(::std::move(" << fixKwd("__ice_" + (*q)->name()) << "))"; + } + else + { + H << nl << fixKwd((*q)->name()) << "(" << fixKwd("__ice_" + (*q)->name()) << ")"; + } + } + + H.dec(); + H << sb; + H << eb; + } + H << sp; + + H << nl << "virtual ::std::string ice_id() const;"; + C << sp << nl << "::std::string" << nl << scoped.substr(2) << "::ice_id() const"; + C << sb; + if(p->isLocal()) + { + C << nl << "return \"" << p->scoped() << "\";" << ";"; + } + else + { + C << nl << "return " << p->flattenedScope() << p->name() << "_init.typeId" << ";"; + } + C << eb; + + StringList metaData = p->getMetaData(); + if(find(metaData.begin(), metaData.end(), "cpp:ice_print") != metaData.end()) + { + H << nl << "virtual void ice_print(::std::ostream&) const;"; + } + + H << nl << "virtual void ice_throw() const;"; + C << sp << nl << "void" << nl << scoped.substr(2) << "::ice_throw() const"; + C << sb; + C << nl << "throw *this;"; + C << eb; + + if(!p->isLocal() && p->usesClasses(false)) + { + if(!base || (base && !base->usesClasses(false))) + { + H << sp << nl << "virtual bool __usesClasses() const;"; + + 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"); + string typeId = p->flattenedScope() + p->name() + "_init.typeId"; + + if(preserved && !basePreserved) + { + H << sp << nl << "virtual void __write(::Ice::OutputStream*) const;"; + H << nl << "virtual void __read(::Ice::InputStream*);"; + } + + H.dec(); + H << sp << nl << "protected:"; + H.inc(); + H << sp; + H << nl << "virtual void __writeImpl(::Ice::OutputStream*) const;"; + H << nl << "virtual void __readImpl(::Ice::InputStream*);"; + + if(preserved && !basePreserved) + { + H << sp << nl << "::std::shared_ptr<::Ice::SlicedData> __slicedData;"; + + C << sp << nl << "void" << nl << scoped.substr(2) << "::__write(::Ice::OutputStream* __os) const"; + C << sb; + C << nl << "__os->startException(__slicedData);"; + C << nl << "__writeImpl(__os);"; + C << nl << "__os->endException();"; + C << eb; + + C << sp << nl << "void" << nl << scoped.substr(2) << "::__read(::Ice::InputStream* __is)"; + C << sb; + C << nl << "__is->startException();"; + C << nl << "__readImpl(__is);"; + C << nl << "__slicedData = __is->endException(true);"; + C << eb; + } + + C << sp << nl << "void" << nl << scoped.substr(2) << "::__writeImpl(::Ice::OutputStream* __os) const"; + C << sb; + C << nl << "__os->startSlice(" << typeId << ", -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(::Ice::InputStream* __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. + // But we do this only once per source file, because a single instance is sufficient to initialize + // all of the globals in a shared library. + // + if(!_doneStaticSymbol) + { + _doneStaticSymbol = true; + H << sp << nl << "static " << name << " __" << p->name() << "_init;"; + } + } + + _useWstring = resetUseWstring(_useWstringHist); +} + +bool +Slice::Gen::Cpp11TypesVisitor::visitStructStart(const StructPtr& p) +{ + DataMemberList dataMembers = p->dataMembers(); + _useWstring = setUseWstring(p, _useWstringHist, _useWstring); + + string name = fixKwd(p->name()); + + + H << sp << nl << "struct " << name; + H << sb; + + return true; +} + +void +Slice::Gen::Cpp11TypesVisitor::visitStructEnd(const StructPtr& p) +{ + string name = fixKwd(p->name()); + string scoped = fixKwd(p->scoped()); + string scope = fixKwd(p->scope()); + + DataMemberList dataMembers = p->dataMembers(); + + vector<string> params; + vector<string>::const_iterator pi; + + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + params.push_back(fixKwd((*q)->name())); + } + + bool containsSequence = false; + if((Dictionary::legalKeyType(p, containsSequence) && !containsSequence)) + { + H << sp << nl << "bool operator==(const " << name << "& __rhs) const"; + H << sb; + 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 << sb; + H << nl << "return false;"; + H << eb; + } + H << nl << "return true;"; + H << eb; + H << sp << nl << "bool operator<(const " << name << "& __rhs) const"; + H << sb; + 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 << sb; + H << nl << "return true;"; + H << eb; + H << nl << "else if(__rhs." << *pi << " < " << *pi << ')'; + H << sb; + H << nl << "return false;"; + H << eb; + } + H << nl << "return false;"; + H << eb; + + H << sp << nl << "bool operator!=(const " << name << "& __rhs) const"; + H << sb; + H << nl << "return !operator==(__rhs);"; + H << eb; + H << nl << "bool operator<=(const " << name << "& __rhs) const"; + H << sb; + H << nl << "return operator<(__rhs) || operator==(__rhs);"; + H << eb; + H << nl << "bool operator>(const " << name << "& __rhs) const"; + H << sb; + H << nl << "return !operator<(__rhs) && !operator==(__rhs);"; + H << eb; + H << nl << "bool operator>=(const " << name << "& __rhs) const"; + H << sb; + H << nl << "return !operator<(__rhs);"; + H << eb; + } + 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, true) << ' ' << name; + + string defaultValue = p->defaultValue(); + if(!defaultValue.empty()) + { + 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, true); + StringList metaData = p->getMetaData(); + + string seqType = findMetaData(metaData, _useWstring); + H << sp; + + if(!seqType.empty()) + { + H << nl << "typedef " << seqType << ' ' << name << ';'; + } + else + { + H << nl << "typedef ::std::vector<" << (s[0] == ':' ? " " : "") << s << "> " << name << ';'; + } +} + +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, true); + if(ks[0] == ':') + { + ks.insert(0, " "); + } + string vs = typeToString(valueType, p->valueMetaData(), typeCtx, true); + + H << sp << nl << "typedef ::std::map<" << ks << ", " << vs << "> " << name << ';'; + } + else + { + // + // A custom dictionary + // + H << sp << nl << "typedef " << dictType << ' ' << name << ';'; + } +} + +Slice::Gen::Cpp11ProxyVisitor::Cpp11ProxyVisitor(Output& h, Output& c, const string& dllExport) : + H(h), C(c), _dllExport(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 " << _dllExport << 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 << "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 << eb << ';'; + + string suffix = p->isInterface() ? "" : "Disp"; + string scoped = fixKwd(p->scoped() + "Prx"); + + C << sp; + C << nl << "const ::std::string&" << nl << scoped.substr(2) << "::ice_staticId()"; + C << sb; + C << nl << "return "<< fixKwd(p->scope() + p->name() + suffix).substr(2) << "::ice_staticId();"; + C << eb; + + _useWstring = resetUseWstring(_useWstringHist); +} + +void +Slice::Gen::Cpp11ProxyVisitor::visitOperation(const OperationPtr& p) +{ + string name = p->name(); + string flatName = p->flattenedScope() + p->name() + "_name"; + + TypePtr ret = p->returnType(); + + bool retIsOpt = p->returnIsOptional(); + string retS = returnTypeToString(ret, retIsOpt, p->getMetaData(), _useWstring | TypeContextAMIEnd, true); + + ContainerPtr container = p->container(); + ClassDefPtr cl = ClassDefPtr::dynamicCast(container); + + vector<string> params; + vector<string> paramsDecl; + + vector<string> lambdaParams; + vector<string> lambdaParamsDecl; + + vector<string> futureParamsDecl; + + vector<string> lambdaOutParams; + vector<string> lambdaOutParamsDecl; + + ParamDeclList paramList = p->parameters(); + ParamDeclList inParams; + ParamDeclList outParams; + + string returnValueS = "returnValue"; + + bool lambdaOutParamsHasOpt = false; + if(ret) + { + lambdaOutParams.push_back(retS); + lambdaOutParamsDecl.push_back(retS + " returnValue"); + lambdaOutParamsHasOpt |= p->returnIsOptional(); + } + + for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q) + { + string paramName = fixKwd(paramPrefix + (*q)->name()); + + StringList metaData = (*q)->getMetaData(); + string typeString; + string outputTypeString; + string typeStringEndAMI; + if((*q)->isOutParam()) + { + typeString = typeToString((*q)->type(), (*q)->optional(), metaData, _useWstring, true); + outputTypeString = outputTypeToString((*q)->type(), (*q)->optional(), metaData, _useWstring, true); + } + else + { + typeString = inputTypeToString((*q)->type(), (*q)->optional(), metaData, _useWstring, true); + } + + if(!(*q)->isOutParam()) + { + params.push_back(typeString); + paramsDecl.push_back(typeString + ' ' + paramName); + + lambdaParams.push_back(typeString); + lambdaParamsDecl.push_back(typeString + ' ' + paramName); + + futureParamsDecl.push_back(typeString + ' ' + paramName); + + inParams.push_back(*q); + } + else + { + params.push_back(outputTypeString); + paramsDecl.push_back(outputTypeString + ' ' + paramName); + + lambdaOutParams.push_back(typeString); + lambdaOutParamsDecl.push_back(typeString + ' ' + paramName); + lambdaOutParamsHasOpt |= (*q)->optional(); + + outParams.push_back(*q); + if((*q)->name() == "returnValue") + { + returnValueS = "_returnValue"; + } + } + } + + string scoped = fixKwd(cl->scope() + cl->name() + "Prx" + "::").substr(2); + + string futureT; + if(lambdaOutParams.empty()) + { + futureT = "void"; + } + else if(lambdaOutParams.size() == 1) + { + futureT = lambdaOutParams[0]; + } + else + { + futureT = "Result_" + name; + } + + if(lambdaOutParams.size() > 1) + { + // We need to generate a Result_ struct. + H << sp; + H << nl << "struct Result_" << name; + H << sb; + for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end(); ++q) + { + string typeString = typeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring, true); + H << nl << typeString << " " << fixKwd((*q)->name()) << ";"; + } + if(ret) + { + H << nl << retS << " " << returnValueS << ";"; + } + H << eb << ";"; + } + + string deprecateSymbol = getDeprecateSymbol(p, cl); + + // + // Synchronous operation + // + H << sp << nl << deprecateSymbol << retS << ' ' << fixKwd(name) << spar << paramsDecl; + H << "const ::Ice::Context& __ctx = Ice::noExplicitContext" << epar; + H << sb; + H << nl; + if(lambdaOutParams.size() == 1) + { + if(ret) + { + H << "return "; + } + else + { + H << paramPrefix << (*outParams.begin())->name() << " = "; + } + } + else if(lambdaOutParams.size() > 1) + { + H << "auto __result = "; + } + if(futureT == "void") + { + H << nl << "makePromiseOutgoing"; + } + else + { + H << nl << "makePromiseOutgoing<" << futureT << ">"; + } + H << spar << "true, this" << string("&" + scoped + "__" + name); + for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end(); ++q) + { + H << fixKwd(paramPrefix + (*q)->name()); + } + H << "__ctx" << epar << ".get();"; + if(lambdaOutParams.size() > 1) + { + for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end(); ++q) + { + H << nl << paramPrefix << (*q)->name() << " = "; + if(isMovable((*q)->type())) + { + H << "::std::move(__result." << fixKwd((*q)->name()) << ");"; + } + else + { + H << "__result." << fixKwd((*q)->name()) << ";"; + } + } + if(ret) + { + if(isMovable(ret)) + { + H << nl << "return ::std::move(__result." << returnValueS << ");"; + } + else + { + H << nl << "return __result." << returnValueS << ";"; + } + } + } + H << eb; + + // + // Lambda based asynchronous operation + // + H << sp; + H << nl << "::std::function<void ()>"; + H << nl << name << "_async("; + H.useCurrentPosAsIndent(); + if(!lambdaParamsDecl.empty()) + { + for(vector<string>::const_iterator q = lambdaParamsDecl.begin(); q != lambdaParamsDecl.end(); ++q) + { + H << *q << ", "; + } + H << nl; + } + H << "::std::function<void " << spar << lambdaOutParams << epar << "> __response,"; + H << nl << "::std::function<void (::std::exception_ptr)> __ex = nullptr,"; + H << nl << "::std::function<void (bool)> __sent = nullptr,"; + H << nl << "const ::Ice::Context& __ctx = Ice::noExplicitContext)"; + H.restoreIndent(); + H << sb; + if(lambdaOutParams.size() > 1) + { + H << nl << "auto __responseCb = [__response](" << futureT << "&& result)"; + H << sb; + H << nl << "__response" << spar; + if(ret) + { + if(isMovable(ret)) + { + H << "::std::move(result." + returnValueS + ")"; + } + else + { + H << "result." + returnValueS; + } + } + for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end(); ++q) + { + if(isMovable((*q)->type())) + { + H << "::std::move(result." + fixKwd((*q)->name()) + ")"; + } + else + { + H << "result." + fixKwd((*q)->name()); + } + } + H << epar << ";" << eb << ";"; + } + if(futureT == "void") + { + H << nl << "return makeLambdaOutgoing" << spar; + } + else + { + H << nl << "return makeLambdaOutgoing<" << futureT << ">" << spar; + } + H << (lambdaOutParams.size() > 1 ? "__responseCb" : "__response") << "__ex" << "__sent" << "this"; + H << string("&" + scoped + "__" + name); + for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end(); ++q) + { + H << fixKwd(paramPrefix + (*q)->name()); + } + H << "__ctx" << epar << ";"; + H << eb; + + // + // Promise based asynchronous operation + // + H << sp; + H << nl << "template<template<typename> class P = ::std::promise>"; + H << nl << deprecateSymbol << "auto " << name << "_async" << spar << futureParamsDecl; + H << "const ::Ice::Context& __ctx = Ice::noExplicitContext" << epar; + H.inc(); + H << nl << "-> decltype(::std::declval<P<" << futureT << ">>().get_future())"; + H.dec(); + H << sb; + if(futureT == "void") + { + H << nl << "return makePromiseOutgoing<P>" << spar; + } + else + { + H << nl << "return makePromiseOutgoing<" << futureT << ", P>" << spar; + } + H << "false, this" << string("&" + scoped + "__" + name); + for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end(); ++q) + { + H << fixKwd(paramPrefix + (*q)->name()); + } + H << "__ctx" << epar << ";"; + H << eb; + + // + // Private implementation + // + H << sp; + H << nl << "void __" << name << spar; + H << "const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<" + futureT + ">>&"; + H << lambdaParams; + H << "const ::Ice::Context& = Ice::noExplicitContext"; + H << epar << ";"; + + C << sp; + C << nl << "void" << nl << scoped << "__" << name << spar; + C << "const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<" + futureT + ">>& __outAsync"; + C << lambdaParamsDecl << "const ::Ice::Context& __ctx"; + C << epar; + C << sb; + if(p->returnsData()) + { + C << nl << "__checkAsyncTwowayOnly(" << flatName << ");"; + } + C << nl << "__outAsync->invoke(" << flatName << ", "; + C << operationModeToString(p->sendMode(), true) << ", " << opFormatTypeToString(p) << ", __ctx, "; + C.inc(); + C << nl; + if(inParams.empty()) + { + C << "nullptr"; + } + else + { + C << "[&](::Ice::OutputStream* __os)"; + C << sb; + writeMarshalCode(C, inParams, 0, true, TypeContextInParam); + if(p->sendsClasses(false)) + { + C << nl << "__os->writePendingObjects();"; + } + C << eb; + } + C << "," << nl; + + ExceptionList throws = p->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; + } + + if(lambdaOutParams.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. + // + C << "," << nl << "[&](::Ice::InputStream* __is)"; + C << sb; + C << nl << futureT << " v;"; + ParamDeclList optionals; + for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end(); ++q) + { + if((*q)->optional()) + { + optionals.push_back(*q); + } + else + { + string name = "v." + fixKwd((*q)->name()); + writeMarshalUnmarshalCode(C, (*q)->type(), false, 0, name, false, (*q)->getMetaData()); + } + } + if(ret && !retIsOpt) + { + string name = "v." + returnValueS; + writeMarshalUnmarshalCode(C, ret, false, 0, name, false, p->getMetaData()); + } + + // + // Sort optional parameters by tag. + // + class SortFn + { + public: + static bool compare(const ParamDeclPtr& lhs, const ParamDeclPtr& rhs) + { + return lhs->tag() < rhs->tag(); + } + }; + optionals.sort(SortFn::compare); + + // + // Marshal optional parameters. + // + bool checkReturnType = ret && retIsOpt; + for(ParamDeclList::const_iterator q = optionals.begin(); q != optionals.end(); ++q) + { + if(checkReturnType && p->returnTag() < (*q)->tag()) + { + string name = "v." + returnValueS; + writeMarshalUnmarshalCode(C, ret, true, p->returnTag(), name, false, p->getMetaData()); + checkReturnType = false; + } + string name = "v." + fixKwd((*q)->name()); + writeMarshalUnmarshalCode(C, (*q)->type(), true, (*q)->tag(), name, false, (*q)->getMetaData()); + } + if(checkReturnType) + { + string name = "v." + returnValueS; + writeMarshalUnmarshalCode(C, ret, true, p->returnTag(), name, false, p->getMetaData()); + } + if(p->returnsClasses(false)) + { + C << nl << "__is->readPendingObjects();"; + } + C << nl << "return v;"; + C << eb; + } + else if(lambdaOutParamsHasOpt) + { + // + // If there's only one optional ret/out parameter, we still need to generate + // a read method, we can't rely on the default read method which wouldn't + // known which tag to use. + // + C << "," << nl << "[&](::Ice::InputStream* __is)"; + C << sb; + C << nl << futureT << " v;"; + if(p->returnIsOptional()) + { + writeMarshalUnmarshalCode(C, ret, true, p->returnTag(), "v", false, p->getMetaData()); + } + else + { + assert(outParams.size() == 1); + ParamDeclPtr q = (*outParams.begin()); + writeMarshalUnmarshalCode(C, q->type(), true, q->tag(), "v", false, q->getMetaData()); + } + C << nl << "return v;"; + C << eb; + } + else if(p->returnsClasses(false)) + { + C << "," << nl << "[&](::Ice::InputStream* __is)"; + C << sb; + C << nl << futureT << " v;"; + if(ret) + { + writeMarshalUnmarshalCode(C, ret, false, 0, "v", false, p->getMetaData()); + } + else + { + assert(outParams.size() == 1); + ParamDeclPtr q = (*outParams.begin()); + writeMarshalUnmarshalCode(C, q->type(), false, 0, "v", false, q->getMetaData()); + } + C << nl << "__is->readPendingObjects();"; + C << nl << "return v;"; + C << eb; + } + + C.dec(); + + C << ");" << eb; +} + +void +Slice::Gen::Cpp11TypesVisitor::visitEnum(const EnumPtr& p) +{ + bool unscoped = findMetaData(p->getMetaData()) == "%unscoped"; + H << sp << nl << "enum "; + if(!unscoped) + { + H << "class "; + } + H << fixKwd(p->name()); + if(!unscoped && p->maxValue() <= 0xFF) + { + H << " : unsigned char"; + } + H << sb; + + EnumeratorList enumerators = p->getEnumerators(); + // + // Check if any of the enumerators were assigned an explicit value. + // + const bool explicitValue = p->explicitValue(); + for(EnumeratorList::const_iterator en = enumerators.begin(); en != enumerators.end();) + { + H << nl << fixKwd((*en)->name()); + // + // If any of the enumerators were assigned an explicit value, we emit + // an explicit value for *all* enumerators. + // + if(explicitValue) + { + H << " = " << int64ToString((*en)->value()); + } + if(++en != enumerators.end()) + { + H << ','; + } + } + H << eb << ';'; +} + +void +Slice::Gen::Cpp11TypesVisitor::visitConst(const ConstPtr& p) +{ + H << sp; + H << nl << (isConstexprType(p->type()) ? "constexpr " : "const ") << typeToString(p->type(), p->typeMetaData(), _useWstring, true) << " " << 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), + _doneStaticSymbol(false), + _useWstring(false) +{ +} + +void +Slice::Gen::Cpp11ObjectVisitor::emitDataMember(const DataMemberPtr& p) +{ + string name = fixKwd(p->name()); + H << sp << nl << typeToString(p->type(), p->optional(), p->getMetaData(), _useWstring, true) << ' ' << name; + + string defaultValue = p->defaultValue(); + if(!defaultValue.empty()) + { + 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 " << _dllExport << 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(); + + // + // In C++, a nested type cannot have the same name as the enclosing type + // + if(p->name() != "PointerType") + { + H << nl << "typedef ::std::shared_ptr<" << name << "> PointerType;"; + } + + vector<string> params; + vector<string> allTypes; + vector<string> allParamDecls; + + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + params.push_back(fixKwd((*q)->name())); + } + + for(DataMemberList::const_iterator q = allDataMembers.begin(); q != allDataMembers.end(); ++q) + { + string typeName = inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring); + allTypes.push_back(typeName); + allParamDecls.push_back(typeName + " __ice_" + (*q)->name()); + } + + if(!p->isInterface()) + { + if(p->hasDefaultValues()) + { + H << sp << nl << name << "() :"; + H.inc(); + writeDataMemberInitializers(H, dataMembers, _useWstring, true); + H.dec(); + H << sb; + H << eb; + } + else + { + H << sp << nl << name << "()"; + H << sb << eb; + } + + emitOneShotConstructor(p); + H << sp; + } + + 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 = true; + DataMemberList dataMembers = p->dataMembers(); + bool prot = p->hasMetaData("protected"); + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + if(prot || (*q)->hasMetaData("protected")) + { + if(!inProtected) + { + H.dec(); + H << sp << nl << "protected:"; + H.inc(); + inProtected = true; + } + } + else + { + if(inProtected) + { + H.dec(); + H << sp << nl << "public:"; + H.inc(); + inProtected = false; + } + } + + emitDataMember(*q); + } + + if(!p->isAbstract()) + { + if(inProtected) + { + H.dec(); + H << sp << nl << "public:"; + H.inc(); + inProtected = false; + } + H << sp << nl << "virtual ~" << fixKwd(p->name()) << "() = default;"; + } + + 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; + TypePtr ret = p->returnType(); + string retS = returnTypeToString(ret, p->returnIsOptional(), p->getMetaData(), typeCtx, true); + + 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, true); + } + else + { + inParams.push_back(*q); + typeString = inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), typeCtx, true); + } + + if(q != paramList.begin()) + { + params += ", "; + paramsDecl += ", "; + args += ", "; + } + + params += typeString; + paramsDecl += typeString; + paramsDecl += ' '; + paramsDecl += paramName; + args += paramName; + + if(isOutParam) + { + outDecls.push_back(typeString); + } + } + + params += ')'; + paramsDecl += ')'; + args += ')'; + + string isConst = ((p->mode() == Operation::Nonmutating) || p->hasMetaData("cpp:const")) ? " const" : ""; + + string deprecateSymbol = getDeprecateSymbol(p, cl); + + H << sp; + H << nl << deprecateSymbol << "virtual " << retS << ' ' << fixKwd(name) << params << isConst << " = 0;"; + + if(cl->hasMetaData("async-oneway") || p->hasMetaData("async-oneway")) + { + vector<string> paramsDeclAMI; + vector<string> outParamsDeclAMI; + + ParamDeclList paramList = p->parameters(); + for(ParamDeclList::const_iterator r = paramList.begin(); r != paramList.end(); ++r) + { + string paramName = fixKwd((*r)->name()); + + StringList metaData = (*r)->getMetaData(); + string typeString; + if(!(*r)->isOutParam()) + { + typeString = inputTypeToString((*r)->type(), (*r)->optional(), metaData, typeCtx, true); + paramsDeclAMI.push_back(typeString + ' ' + paramName); + } + } + + H << sp; + H << nl << "virtual ::std::function<void ()>"; + H << nl << name << "_async("; + H.useCurrentPosAsIndent(); + for(vector<string>::const_iterator i = paramsDeclAMI.begin(); i != paramsDeclAMI.end(); ++i) + { + H << *i << ","; + } + if(!paramsDeclAMI.empty()) + { + H << nl; + } + H << "::std::function<void (::std::exception_ptr)> exception,"; + H << nl << "::std::function<void (bool)> sent = nullptr) = 0;"; + H.restoreIndent(); + + H << sp; + H << nl << "template<template<typename> class P = ::std::promise>"; + H << nl << deprecateSymbol << "auto " << name << "_async" << spar << paramsDeclAMI << epar; + H.inc(); + H << nl << "-> decltype(::std::declval<P<bool>>().get_future())"; + H.dec(); + H << sb; + H << nl << "using Promise = P<bool>;"; + H << nl << "auto __promise = ::std::make_shared<Promise>();"; + + H << nl << name << "_async("; + H.useCurrentPosAsIndent(); + for(vector<string>::const_iterator i = paramsDeclAMI.begin(); i != paramsDeclAMI.end(); ++i) + { + H << *i << ","; + } + if(!paramsDeclAMI.empty()) + { + H << nl; + } + H << "[__promise](::std::exception_ptr __ex)"; + H << sb; + H << nl << "__promise->set_exception(::std::move(__ex));"; + H << eb << ","; + H << nl << "[__promise](bool __b)"; + H << sb; + H << nl << "__promise->set_value(__b);"; + H << eb << ");"; + H.restoreIndent(); + + H << nl << "return __promise->get_future();"; + H << eb; + } +} + +Slice::Gen::Cpp11InterfaceVisitor::Cpp11InterfaceVisitor(::IceUtilInternal::Output& h, + ::IceUtilInternal::Output& c, + const std::string& dllExport) : + Cpp11ObjectVisitor(h, c, dllExport) +{ +} + +bool +Slice::Gen::Cpp11InterfaceVisitor::visitModuleStart(const ModulePtr& p) +{ + if(!p->hasNonLocalInterfaceDefs()) + { + return false; + } + + _useWstring = setUseWstring(p, _useWstringHist, _useWstring); + string name = fixKwd(p->name()); + H << sp << nl << "namespace " << name << nl << '{'; + return true; +} + +void +Slice::Gen::Cpp11InterfaceVisitor::visitModuleEnd(const ModulePtr&) +{ + H << sp; + H << nl << '}'; + + _useWstring = resetUseWstring(_useWstringHist); +} + +bool +Slice::Gen::Cpp11InterfaceVisitor::visitClassDefStart(const ClassDefPtr& p) +{ + if(p->isLocal() || (!p->isInterface() && p->allOperations().empty())) + { + return false; + } + + 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(); + } + DataMemberList dataMembers = p->dataMembers(); + DataMemberList allDataMembers = p->allDataMembers(); + + 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 << "typedef " << p->name() << "Prx ProxyType;"; + } + + 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 firstIter = ids.begin(); + StringList::const_iterator scopedIter = find(ids.begin(), ids.end(), p->scoped()); + assert(scopedIter != ids.end()); + StringList::difference_type scopedPos = IceUtilInternal::distance(firstIter, scopedIter); + + H << sp; + H << nl << "virtual bool ice_isA(::std::string, const ::Ice::Current& = ::Ice::noExplicitCurrent) const;"; + H << nl << "virtual ::std::vector< ::std::string> ice_ids(const ::Ice::Current& = ::Ice::noExplicitCurrent) const;"; + H << nl << "virtual const ::std::string& ice_id(const ::Ice::Current& = ::Ice::noExplicitCurrent) const;"; + H << nl << "static const ::std::string& ice_staticId();"; + + string flatName = p->flattenedScope() + p->name() + "_ids"; + + C << sp; + C << nl << "bool" << nl << scoped.substr(2) << "::ice_isA(::std::string _s, const ::Ice::Current&) const"; + C << sb; + C << nl << "return ::std::binary_search(" << flatName << ", " << flatName << " + " << ids.size() << ", _s);"; + C << eb; + + C << sp; + C << nl << "::std::vector< ::std::string>" << nl << scoped.substr(2) << "::ice_ids(const ::Ice::Current&) const"; + C << sb; + C << nl << "return ::std::vector< ::std::string>(&" << flatName << "[0], &" << flatName << '[' << ids.size() << "]);"; + C << eb; + + C << sp; + C << nl << "const ::std::string&" << nl << scoped.substr(2) << "::ice_id(const ::Ice::Current&) const"; + C << sb; + C << nl << "return " << flatName << '[' << scopedPos << "];"; + C << eb; + + C << sp; + C << nl << "const ::std::string&" << nl << scoped.substr(2) << "::ice_staticId()"; + C << sb; + C << nl << "return " << flatName << '[' << scopedPos << "];"; + C << eb; + return true; +} + +void +Slice::Gen::Cpp11InterfaceVisitor::visitClassDefEnd(const ClassDefPtr& p) +{ + string suffix = p->isInterface() ? "" : "Disp"; + string scoped = fixKwd(p->scope() + p->name() + suffix); + + string scope = fixKwd(p->scope()); + string name = fixKwd(p->name() + suffix); + ClassList bases = p->bases(); + ClassDefPtr base; + if(!bases.empty() && !bases.front()->isInterface()) + { + base = bases.front(); + } + + OperationList allOps = p->allOperations(); + if(!allOps.empty()) + { + StringList allOpNames; + transform(allOps.begin(), allOps.end(), back_inserter(allOpNames), ::IceUtil::constMemFun(&Contained::name)); + allOpNames.push_back("ice_id"); + allOpNames.push_back("ice_ids"); + allOpNames.push_back("ice_isA"); + allOpNames.push_back("ice_ping"); + allOpNames.sort(); + allOpNames.unique(); + + string flatName = p->flattenedScope() + p->name() + "_ops"; + + H << sp; + H << nl << "virtual ::Ice::DispatchStatus __dispatch(::IceInternal::Incoming&, const ::Ice::Current&);"; + + C << sp; + C << nl << "::Ice::DispatchStatus" << nl << scoped.substr(2) + << "::__dispatch(::IceInternal::Incoming& in, const ::Ice::Current& c)"; + C << sb; + + C << nl << "::std::pair< const ::std::string*, const ::std::string*> r = " + << "::std::equal_range(" << flatName << ", " << flatName << " + " << allOpNames.size() << ", c.operation);"; + C << nl << "if(r.first == r.second)"; + C << sb; + C << nl << "throw ::Ice::OperationNotExistException(__FILE__, __LINE__, c.id, c.facet, c.operation);"; + C << eb; + C << sp; + C << nl << "switch(r.first - " << flatName << ')'; + C << sb; + int i = 0; + for(StringList::const_iterator q = allOpNames.begin(); q != allOpNames.end(); ++q) + { + C << nl << "case " << i++ << ':'; + C << sb; + C << nl << "return ___" << *q << "(in, c);"; + C << eb; + } + C << eb; + C << sp; + C << nl << "assert(false);"; + C << nl << "throw ::Ice::OperationNotExistException(__FILE__, __LINE__, c.id, c.facet, c.operation);"; + C << eb; + } + + H << eb << ';'; +} + +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(); + string retS = returnTypeToString(ret, p->returnIsOptional(), p->getMetaData(), _useWstring, true); + + string params = "("; + string paramsDecl = "("; + string args = "("; + + string paramsAMD; + string argsAMD; + + string responseParams; + 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()); + + 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(), _useWstring, true); + outDecls.push_back(inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring, true)); + } + else + { + inParams.push_back(*q); + typeString = typeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring, true); + } + + if(q != paramList.begin()) + { + params += ", "; + paramsDecl += ", "; + args += ", "; + } + + params += typeString; + paramsDecl += typeString; + paramsDecl += ' '; + paramsDecl += paramName; + args += (isMovable(type) && !isOutParam) ? ("::std::move(" + paramName + ")") : paramName; + } + + if(!paramList.empty()) + { + params += ", "; + paramsDecl += ", "; + args += ", "; + } + + params += "const ::Ice::Current& = ::Ice::noExplicitCurrent)"; + paramsDecl += "const ::Ice::Current& __current)"; + args += "__current)"; + + for(ParamDeclList::iterator q = inParams.begin(); q != inParams.end(); ++q) + { + if(q != inParams.begin()) + { + paramsAMD += ", "; + argsAMD += ", "; + } + paramsAMD += typeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring, true); + if(isMovable((*q)->type())) + { + argsAMD += "::std::move(" + fixKwd(string(paramPrefix) + (*q)->name()) + ")"; + } + else + { + argsAMD += fixKwd(string(paramPrefix) + (*q)->name()); + } + } + + if(ret) + { + string typeString = inputTypeToString(ret, p->returnIsOptional(), p->getMetaData(), _useWstring, true); + responseParams = typeString; + responseParamsDecl = typeString + " __ret"; + if(!outParams.empty()) + { + responseParams += ", "; + responseParamsDecl += ", "; + } + } + + for(ParamDeclList::iterator q = outParams.begin(); q != outParams.end(); ++q) + { + if(q != outParams.begin()) + { + responseParams += ", "; + responseParamsDecl += ", "; + } + string typeString = inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring, true); + responseParams += typeString; + responseParamsDecl += typeString + " " + fixKwd(string(paramPrefix) + (*q)->name()); + } + + string isConst = ((p->mode() == Operation::Nonmutating) || p->hasMetaData("cpp:const")) ? " const" : ""; + bool amd = (cl->hasMetaData("amd") || p->hasMetaData("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. + // +#if defined(__SUNPRO_CC) + throws.sort(derivedToBaseCompare); +#else + throws.sort(Slice::DerivedToBaseCompare()); +#endif + + string deprecateSymbol = getDeprecateSymbol(p, cl); + H << sp; + if(!amd) + { + H << nl << deprecateSymbol << "virtual " << retS << ' ' << fixKwd(name) << params << isConst << " = 0;"; + } + else + { + H << nl << deprecateSymbol << "virtual void " << name << "_async("; + H.useCurrentPosAsIndent(); + H << paramsAMD; + if(!paramsAMD.empty()) + { + H << "," << nl; + } + H << "::std::function<void (" << responseParams << ")>," << nl + << "::std::function<void (::std::exception_ptr)>, const Ice::Current&)" << isConst << " = 0;"; + H.restoreIndent(); + } + + H << sp; + H << nl << "::Ice::DispatchStatus ___" << name << "(::IceInternal::Incoming&, const ::Ice::Current&)" << isConst << ';'; + + C << sp; + C << nl << "::Ice::DispatchStatus" << nl << scope.substr(2) << "___" << name << "(::IceInternal::Incoming& __inS" + << ", const ::Ice::Current& __current)" << isConst; + C << sb; + C << nl << "__checkMode(" << operationModeToString(p->mode(), true) << ", __current.mode);"; + + if(!inParams.empty()) + { + C << nl << "::Ice::InputStream* __is = __inS.startReadParams();"; + writeAllocateCode(C, inParams, 0, true, _useWstring | TypeContextInParam, true); + writeUnmarshalCode(C, inParams, 0, true, TypeContextInParam); + if(p->sendsClasses(false)) + { + C << nl << "__is->readPendingObjects();"; + } + C << nl << "__inS.endReadParams();"; + } + else + { + C << nl << "__inS.readEmptyParams();"; + } + + if(!amd) + { + writeAllocateCode(C, outParams, 0, true, _useWstring, true); + if(!throws.empty()) + { + C << nl << "try"; + C << sb; + } + C << nl; + if(ret) + { + C << retS << " __ret = "; + } + C << fixKwd(name) << args << ';'; + if(ret || !outParams.empty()) + { + C << nl << "auto __os = __inS.__startWriteParams(" << opFormatTypeToString(p) << ");"; + writeMarshalCode(C, outParams, p, true); + if(p->returnsClasses(false)) + { + C << nl << "__os->writePendingObjects();"; + } + C << nl << "__inS.__endWriteParams(true);"; + } + 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;"; + } + } + else + { + C << nl << "auto inS = ::IceInternal::IncomingAsync::create(__inS);"; + C << nl << "auto __exception = [inS](::std::exception_ptr e)"; + C << sb; + C << nl << "try"; + C << sb; + C << nl << "std::rethrow_exception(e);"; + C << eb; + + for(ExceptionList::const_iterator r = throws.begin(); r != throws.end(); ++r) + { + C << nl << "catch(const " << fixKwd((*r)->scoped()) << "& __ex)"; + C << sb; + C << nl <<"if(inS->__validateResponse(false))"; + C << sb; + C << nl << "inS->__writeUserException(__ex, " << opFormatTypeToString(p) << ");"; + C << nl << "inS->__response();"; + C << eb; + C << eb; + } + + C << nl << "catch(const ::std::exception& __ex)"; + C << sb; + C << nl << "inS->ice_exception(__ex);"; + C << eb; + C << nl << "catch(...)"; + C << sb; + C << nl << "inS->ice_exception();"; + C << eb; + C << eb << ";"; + + C << nl << "try"; + C << sb; + + C << nl << name << "_async("; + C.useCurrentPosAsIndent(); + if(!argsAMD.empty()) + { + C << argsAMD << ","; + C << nl; + } + C << "[inS](" << responseParamsDecl << ")"; + C << sb; + C << nl << "if(inS->__validateResponse(true))"; + C << sb; + if(ret || !outParams.empty()) + { + C << nl << "auto __os = inS->__startWriteParams(" << opFormatTypeToString(p) << ");"; + writeMarshalCode(C, outParams, p, true); + if(p->returnsClasses(false)) + { + C << nl << "__os->writePendingObjects();"; + } + C << nl << "inS->__endWriteParams(true);"; + } + else + { + C << nl << "inS->__writeEmptyParams();"; + } + C << nl << "inS->__response();"; + C << eb; + C << eb << ","; + C << nl << "__exception, __current);"; + C.restoreIndent(); + C << eb; + C << nl << "catch(...)"; + C << sb; + C << nl << "__exception(std::current_exception());"; + C << eb; + C << nl << "return ::Ice::DispatchAsync;"; + } + 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 " << _dllExport << 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(); + + // + // In C++, a nested type cannot have the same name as the enclosing type + // + + if(p->name() != "PointerType") + { + H << nl << "typedef ::std::shared_ptr<" << name << "> PointerType;"; + } + + vector<string> params; + vector<string> allTypes; + vector<string> allParamDecls; + + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + params.push_back(fixKwd((*q)->name())); + } + + for(DataMemberList::const_iterator q = allDataMembers.begin(); q != allDataMembers.end(); ++q) + { + string typeName = inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring); + allTypes.push_back(typeName); + allParamDecls.push_back(typeName + " __ice_" + (*q)->name()); + } + + H << sp << nl << name << "() = default;"; + + emitOneShotConstructor(p); + H << sp; + H << nl << "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()); + string typeId = p->flattenedScope() + p->name() + "_init.typeId"; + ClassList bases = p->bases(); + ClassDefPtr base; + if(!bases.empty() && !bases.front()->isInterface()) + { + base = bases.front(); + } + bool basePreserved = p->inheritsMetaData("preserve-slice"); + bool preserved = p->hasMetaData("preserve-slice"); + + if(preserved && !basePreserved) + { + H << sp; + H << nl << "virtual void __write(::Ice::OutputStream*) const;"; + H << nl << "virtual void __read(::Ice::InputStream*);"; + } + + H.dec(); + H << sp << nl << "protected:"; + H.inc(); + H << sp; + H << nl << "virtual void __writeImpl(::Ice::OutputStream*) const;"; + H << nl << "virtual void __readImpl(::Ice::InputStream*);"; + + if(preserved && !basePreserved) + { + C << sp; + C << nl << "void" << nl << scoped.substr(2) << "::__write(::Ice::OutputStream* __os) const"; + C << sb; + C << nl << "__os->startObject(__slicedData);"; + C << nl << "__writeImpl(__os);"; + C << nl << "__os->endObject();"; + C << eb; + + C << sp; + C << nl << "void" << nl << scoped.substr(2) << "::__read(::Ice::InputStream* __is)"; + C << sb; + C << nl << "__is->startObject();"; + C << nl << "__readImpl(__is);"; + C << nl << "__slicedData = __is->endObject(true);"; + C << eb; + } + + C << sp; + C << nl << "void" << nl << scoped.substr(2) << "::__writeImpl(::Ice::OutputStream* __os) const"; + C << sb; + C << nl << "__os->startSlice(" << typeId << ", " << 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; + C << nl << "void" << nl << scoped.substr(2) << "::__readImpl(::Ice::InputStream* __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; + + C << sp; + C << nl << "const ::std::string&" << nl << scoped.substr(2) << "::ice_staticId()"; + C << sb; + C << nl << "return " << typeId << ";"; + C << eb; + + // + // Emit data members. Access visibility may be specified by metadata. + // + bool inProtected = true; + DataMemberList dataMembers = p->dataMembers(); + bool prot = p->hasMetaData("protected"); + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + if(prot || (*q)->hasMetaData("protected")) + { + if(!inProtected) + { + H.dec(); + H << sp << nl << "protected:"; + H.inc(); + inProtected = true; + } + } + else + { + if(inProtected) + { + H.dec(); + H << sp << nl << "public:"; + H.inc(); + inProtected = false; + } + } + + emitDataMember(*q); + } + + if(preserved && !basePreserved) + { + if(!inProtected) + { + H.dec(); + H << sp << nl << "protected:"; + H.inc(); + inProtected = true; + } + H << sp << nl << "::std::shared_ptr<::Ice::SlicedData> __slicedData;"; + } + + H << eb << ';'; + + if(!_doneStaticSymbol) + { + // + // We need an instance here to trigger initialization if the implementation is in a static library. + // But we do this only once per source file, because a single instance is sufficient to initialize + // all of the globals in a compilation unit. + // + _doneStaticSymbol = true; + H << sp << nl << "static " << fixKwd(p->name()) << " _" << p->name() << "_init;"; + } + + _useWstring = resetUseWstring(_useWstringHist); +} + +bool +Slice::Gen::Cpp11ValueVisitor::visitExceptionStart(const ExceptionPtr&) +{ + return false; +} + +bool +Slice::Gen::Cpp11ValueVisitor::visitStructStart(const StructPtr&) +{ + return false; +} + +void +Slice::Gen::Cpp11ValueVisitor::visitOperation(const OperationPtr&) +{ +} + + +bool +Slice::Gen::Cpp11ObjectVisitor::emitVirtualBaseInitializers(const ClassDefPtr& derived, const ClassDefPtr& base) +{ + DataMemberList allDataMembers = base->allDataMembers(); + if(allDataMembers.empty()) + { + return false; + } + + string upcall = "("; + for(DataMemberList::const_iterator q = allDataMembers.begin(); q != allDataMembers.end(); ++q) + { + if(q != allDataMembers.begin()) + { + upcall += ", "; + } + if(isMovable((*q)->type())) + { + upcall += "::std::move(__ice_" + (*q)->name() + ")"; + } + else + { + upcall += "__ice_" + (*q)->name(); + } + } + upcall += ")"; + + if(base->isLocal()) + { + H << nl << fixKwd(base->scoped()); + } + else + { + H << nl << "Ice::ValueHelper<" << fixKwd(derived->scoped()) << ", " << fixKwd(base->scoped()) << ">"; + } + H << upcall; + return true; +} + +void +Slice::Gen::Cpp11ObjectVisitor::emitOneShotConstructor(const ClassDefPtr& p) +{ + DataMemberList allDataMembers = p->allDataMembers(); + + if(!allDataMembers.empty()) + { + vector<string> allParamDecls; + DataMemberList dataMembers = p->dataMembers(); + + for(DataMemberList::const_iterator q = allDataMembers.begin(); q != allDataMembers.end(); ++q) + { + string typeName = inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring, true); + allParamDecls.push_back(typeName + " __ice_" + (*q)->name()); + } + + H << sp << nl; + if(allParamDecls.size() == 1) + { + H << "explicit "; + } + H << fixKwd(p->name()) << spar << allParamDecls << epar << " :"; + H.inc(); + + ClassList bases = p->bases(); + + if(!bases.empty() && !bases.front()->isInterface()) + { + if(emitVirtualBaseInitializers(p, bases.front())) + { + if(!dataMembers.empty()) + { + H << ','; + } + } + } + + if(!dataMembers.empty()) + { + H << nl; + } + + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + if(q != dataMembers.begin()) + { + H << ',' << nl; + } + string memberName = fixKwd((*q)->name()); + if(isMovable((*q)->type())) + { + H << memberName << "(::std::move(" << "__ice_" << (*q)->name() << "))"; + } + else + { + H << memberName << '(' << "__ice_" << (*q)->name() << ')'; + } + } + + H.dec(); + H << sb; + H << eb; + } +} + +Slice::Gen::Cpp11StreamVisitor::Cpp11StreamVisitor(Output& h, Output& c, const string& dllExport) : + H(h), + C(c), + _dllExport(dllExport) +{ +} + +bool +Slice::Gen::Cpp11StreamVisitor::visitModuleStart(const ModulePtr& m) +{ + if(!m->hasNonLocalContained(Contained::ContainedTypeStruct) && + !m->hasNonLocalContained(Contained::ContainedTypeEnum)) + { + return false; + } + + if(UnitPtr::dynamicCast(m->container())) + { + // + // Only emit this for the top-level module. + // + H << sp; + H << nl << "namespace Ice" << nl << '{'; + + 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; + + DataMemberList dataMembers = p->dataMembers(); + + H << nl << "template<class S>"; + H << nl << "struct StreamWriter<" << scoped << ", S>"; + H << sb; + H << nl << "static void write(S* __os, const " << scoped << "& v)"; + H << sb; + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + writeMarshalUnmarshalDataMemberInHolder(H, "v.", *q, true); + } + H << eb; + H << eb << ";" << nl; + + H << nl << "template<class S>"; + H << nl << "struct StreamReader<" << scoped << ", S>"; + H << sb; + H << nl << "static void read(S* __is, " << scoped << "& v)"; + H << sb; + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + writeMarshalUnmarshalDataMemberInHolder(H, "v.", *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< " << scoped << ", ::Ice::OutputStream>;"; + H << nl << "template struct " << _dllExport << "StreamReader< " << scoped << ", ::Ice::InputStream>;"; + 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< " << scoped << ", ::Ice::OutputStream>;"; + C << nl << "template struct " << _dllExport << "StreamReader< " << scoped << ", ::Ice::InputStream>;"; + C << nl << "#endif"; + } + return false; +} + +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 << "typedef ::std::shared_ptr<" << name << "> " << p->name() << "Ptr;"; + + if(!p->isLocal()) + { + ClassDefPtr def = p->definition(); + if(p->isInterface() || (def && !def->allOperations().empty())) + { + H << nl << "class " << p->name() << "Prx;"; + H << nl << "typedef ::std::shared_ptr<" << p->name() << "Prx> " << p->name() << "PrxPtr;"; + } + } +} + +Slice::Gen::Cpp11ImplVisitor::Cpp11ImplVisitor(Output& h, Output& c, const string& dllExport) : + H(h), C(c), _dllExport(dllExport), _useWstring(false) +{ +} + +string +Slice::Gen::Cpp11ImplVisitor::defaultValue(const TypePtr& type, const StringList& metaData) const +{ + BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); + if(builtin) + { + switch(builtin->kind()) + { + case Builtin::KindBool: + { + return "false"; + } + case Builtin::KindByte: + case Builtin::KindShort: + case Builtin::KindInt: + case Builtin::KindLong: + { + return "0"; + } + case Builtin::KindFloat: + case Builtin::KindDouble: + { + return "0.0"; + } + case Builtin::KindString: + { + return "::std::string()"; + } + case Builtin::KindValue: + case Builtin::KindObject: + case Builtin::KindObjectProxy: + case Builtin::KindLocalObject: + { + return "nullptr"; + } + } + } + else + { + ProxyPtr prx = ProxyPtr::dynamicCast(type); + + if(ProxyPtr::dynamicCast(type) || ClassDeclPtr::dynamicCast(type)) + { + return "nullptr"; + } + + StructPtr st = StructPtr::dynamicCast(type); + if(st) + { + return fixKwd(st->scoped()) + "()"; + } + + EnumPtr en = EnumPtr::dynamicCast(type); + if(en) + { + EnumeratorList enumerators = en->getEnumerators(); + return fixKwd(en->scoped() + "::" + enumerators.front()->name()); + } + + SequencePtr seq = SequencePtr::dynamicCast(type); + if(seq) + { + return typeToString(seq, metaData, _useWstring, true) + "()"; + } + + 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, true); + + 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, true) << "," << nl; + } + + if(ret) + { + string typeS = inputTypeToString(ret, op->returnIsOptional(), op->getMetaData(), _useWstring, true); + 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, true); + 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 << ';'; + 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, true); + 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, true); + } + else + { + typeString = typeToString((*q)->type(), (*q)->optional(), metaData, _useWstring, true); + } + 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 << ';'; + + 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, true) << " " + << fixKwd((*q)->name()); + } + else + { + C << typeToString((*q)->type(), (*q)->optional(), metaData, _useWstring, true)<< " /*" + << 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; +} |