diff options
Diffstat (limited to 'cpp/src/slice2cpp')
-rw-r--r-- | cpp/src/slice2cpp/Gen.cpp | 3578 | ||||
-rw-r--r-- | cpp/src/slice2cpp/Gen.h | 251 |
2 files changed, 3731 insertions, 98 deletions
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp index e9e771bf64f..c0ae7f2fa25 100644 --- a/cpp/src/slice2cpp/Gen.cpp +++ b/cpp/src/slice2cpp/Gen.cpp @@ -29,6 +29,56 @@ 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 getDeprecateSymbol(const ContainedPtr& p1, const ContainedPtr& p2) { @@ -48,7 +98,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) @@ -108,7 +158,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) { @@ -364,10 +421,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>"; @@ -375,7 +432,9 @@ 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/Value.h>"; H << "\n#include <Ice/AsyncResult.h>"; H << "\n#include <Ice/Incoming.h>"; if(p->hasContentsWithMetaData("amd")) @@ -398,7 +457,7 @@ Slice::Gen::generate(const UnitPtr& p) H << "\n#include <Ice/Proxy.h>"; } - if(p->hasNonLocalDataOnlyClasses() || p->hasNonLocalExceptions()) + if(p->hasNonLocalClassDefs() || p->hasNonLocalExceptions()) { H << "\n#include <Ice/FactoryTableInit.h>"; } @@ -482,95 +541,203 @@ Slice::Gen::generate(const UnitPtr& p) _dllExport += " "; } - ProxyDeclVisitor proxyDeclVisitor(H, C, _dllExport); - p->visit(&proxyDeclVisitor, false); + H << sp; + H.zeroIndent(); + H << nl << "#ifndef ICE_CPP11_MAPPING // C++98 mapping"; + H.restoreIndent(); + + C << sp; + C.zeroIndent(); + C << nl << "#ifndef ICE_CPP11_MAPPING // C++98 mapping"; + C.restoreIndent(); + { + ProxyDeclVisitor proxyDeclVisitor(H, C, _dllExport); + p->visit(&proxyDeclVisitor, false); - ObjectDeclVisitor objectDeclVisitor(H, C, _dllExport); - p->visit(&objectDeclVisitor, false); + ObjectDeclVisitor objectDeclVisitor(H, C, _dllExport); + p->visit(&objectDeclVisitor, false); - TypesVisitor typesVisitor(H, C, _dllExport, _stream); - p->visit(&typesVisitor, false); + TypesVisitor typesVisitor(H, C, _dllExport, _stream); + p->visit(&typesVisitor, false); - StreamVisitor streamVisitor(H, C, _dllExport); - p->visit(&streamVisitor, false); + StreamVisitor streamVisitor(H, C, _dllExport); + p->visit(&streamVisitor, false); - AsyncVisitor asyncVisitor(H, C, _dllExport); - p->visit(&asyncVisitor, false); + AsyncVisitor asyncVisitor(H, C, _dllExport); + p->visit(&asyncVisitor, false); - AsyncImplVisitor asyncImplVisitor(H, C, _dllExport); - p->visit(&asyncImplVisitor, 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); + // + // 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); + ProxyVisitor proxyVisitor(H, C, _dllExport); + p->visit(&proxyVisitor, false); - ObjectVisitor objectVisitor(H, C, _dllExport, _stream); - p->visit(&objectVisitor, false); + ObjectVisitor objectVisitor(H, C, _dllExport, _stream); + 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); + // + // 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(_impl) - { - implH << "\n#include <"; - if(_include.size()) + if(_impl) { - implH << _include << '/'; - } - implH << _base << "." << _headerExtension << ">"; + implH << "\n#include <"; + if(_include.size()) + { + implH << _include << '/'; + } + implH << _base << "." << _headerExtension << ">"; - writeExtraHeaders(implC); + writeExtraHeaders(implC); - implC << "\n#include <"; - if(_include.size()) - { - implC << _include << '/'; + implC << "\n#include <"; + if(_include.size()) + { + implC << _include << '/'; + } + implC << _base << "I." << _implHeaderExtension << ">"; + + ImplVisitor implVisitor(implH, implC, _dllExport); + p->visit(&implVisitor, false); } - implC << _base << "I." << _implHeaderExtension << ">"; - ImplVisitor implVisitor(implH, implC, _dllExport); - p->visit(&implVisitor, false); + 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 << "}"; + } + } } + H << sp; + H.zeroIndent(); + H << nl << "#else // C++11 mapping"; + H.restoreIndent(); - if(_checksum) + C << sp; + C.zeroIndent(); + C << nl << "#else // C++11 mapping"; + C.restoreIndent(); { - ChecksumMap map = createChecksums(p); - if(!map.empty()) + Cpp11ProxyDeclVisitor proxyDeclVisitor(H, C, _dllExport); + p->visit(&proxyDeclVisitor, false); + + Cpp11ObjectDeclVisitor objectDeclVisitor(H, C, _dllExport); + p->visit(&objectDeclVisitor, false); + + Cpp11TypesVisitor typesVisitor(H, C, _dllExport, _stream); + p->visit(&typesVisitor, false); + + Cpp11StreamVisitor streamVisitor(H, C, _dllExport); + p->visit(&streamVisitor, false); + + Cpp11ProxyVisitor proxyVisitor(H, C, _dllExport); + p->visit(&proxyVisitor, false); + + Cpp11InterfaceTraitsVisitor interfaceTraitsVisitor(H, C, _dllExport); + p->visit(&interfaceTraitsVisitor, false); + + Cpp11LocalObjectVisitor localObjectVisitor(H, C, _dllExport, _stream); + p->visit(&localObjectVisitor, false); + + Cpp11InterfaceVisitor interfaceVisitor(H, C, _dllExport, _stream); + p->visit(&interfaceVisitor, false); + + Cpp11ValueVisitor valueVisitor(H, C, _dllExport, _stream); + p->visit(&valueVisitor, false); + + // TODO + /*if(_impl) { - 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()) + { + implH << _include << '/'; + } + 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); + } + + if(_checksum) + { + ChecksumMap map = createChecksums(p); + if(!map.empty()) { - 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) + 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) { - str << static_cast<int>(*r); + 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 << str.str() << "\","; + C << nl << "0"; + C << eb << ';'; + C << nl << "const IceInternal::SliceChecksumInit __sliceChecksumInit(__sliceChecksums);"; + C << sp << nl << "}"; } - C << nl << "0"; - C << eb << ';'; - C << nl << "const IceInternal::SliceChecksumInit __sliceChecksumInit(__sliceChecksums);"; - C << sp << nl << "}"; - } + }*/ + H << sp; + H.zeroIndent(); + H << nl << "#endif"; + H.restoreIndent(); + + C << sp; + C.zeroIndent(); + C << nl << "#endif"; + C.restoreIndent(); } } @@ -1789,16 +1956,7 @@ 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" + H << nl << deprecateSymbol << retS << ' ' << fixKwd(name) << spar << paramsDecl << "const ::Ice::Context& __ctx = ::Ice::noExplicitContext" << epar; H << sb; H << nl; @@ -1810,7 +1968,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) H << eb; H.zeroIndent(); - H << nl << "#ifdef ICE_CPP11"; + H << nl << "#ifdef ICE_CPP11_COMPILER"; H.restoreIndent(); string retEndArg = getEndArg(ret, p->getMetaData(), "__ret"); @@ -1845,12 +2003,12 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) H << sb; if(p->returnsData()) { - H << nl << "return __begin_" << name << spar << argsAMI << "0, __response, __exception, __sent" << epar << ";"; + H << nl << "return __begin_" << name << spar << argsAMI << "&::Ice::noExplicitContext, __response, __exception, __sent" << epar << ";"; } else { H << nl << "return begin_" << name << spar << argsAMI - << "0, new ::IceInternal::Cpp11FnOnewayCallbackNC(__response, __exception, __sent)" << epar << ";"; + << "&::Ice::noExplicitContext, new ::IceInternal::Cpp11FnOnewayCallbackNC(__response, __exception, __sent)" << epar << ";"; } H << eb; @@ -1872,7 +2030,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) << "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 << nl << "return begin_" << name << spar << argsAMI << "&::Ice::noExplicitContext, ::Ice::newCallback(__completed, __sent), 0" << epar << ";"; H << eb; // @@ -1994,7 +2152,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) H << sp << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI << epar; H << sb; - H << nl << "return begin_" << name << spar << argsAMI << "0" << "::IceInternal::__dummyCallback" << "0" + H << nl << "return begin_" << name << spar << argsAMI << "&::Ice::noExplicitContext" << "::IceInternal::__dummyCallback" << "0" << epar << ';'; H << eb; @@ -2009,7 +2167,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) << "const ::Ice::CallbackPtr& __del" << "const ::Ice::LocalObjectPtr& __cookie = 0" << epar; H << sb; - H << nl << "return begin_" << name << spar << argsAMI << "0" << "__del" << "__cookie" << epar << ';'; + H << nl << "return begin_" << name << spar << argsAMI << "&::Ice::noExplicitContext" << "__del" << "__cookie" << epar << ';'; H << eb; H << sp << nl << "::Ice::AsyncResultPtr begin_" << name << spar << paramsDeclAMI @@ -2024,7 +2182,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 << "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 @@ -2206,7 +2364,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) if(p->returnsData()) { - C << nl << nl << "#ifdef ICE_CPP11"; + C << nl << nl << "#ifdef ICE_CPP11_COMPILER"; // // COMPILERFIX VC compilers up to VC110 don't support more than 10 parameters with std::function due to @@ -2335,7 +2493,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) { C << nl << "#endif"; } - C << nl << "#endif"; // ICE_CPP11 + C << nl << "#endif"; // ICE_CPP11_COMPILER } C << sp << nl << retS << nl << "IceProxy" << scope << "end_" << name << spar << outParamsDeclAMI @@ -2445,6 +2603,7 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p) C << nl << "throw ::Ice::UnknownUserException(__FILE__, __LINE__, __ex.ice_name());"; C << eb; C << eb; + if(ret || !outParams.empty()) { C << nl << "::IceInternal::BasicStream* __is = __result->__startReadParams();"; @@ -2504,6 +2663,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 @@ -2816,8 +2976,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;"; } @@ -4050,7 +4208,6 @@ void Slice::Gen::AsyncCallbackTemplateVisitor::visitModuleEnd(const ModulePtr&) { _useWstring = resetUseWstring(_useWstringHist); - H << sp << nl << '}'; } @@ -4354,6 +4511,7 @@ Slice::Gen::ImplVisitor::writeDecl(Output& out, const string& name, const TypePt break; } case Builtin::KindString: + case Builtin::KindValue: case Builtin::KindObject: case Builtin::KindObjectProxy: case Builtin::KindLocalObject: @@ -4405,6 +4563,7 @@ Slice::Gen::ImplVisitor::writeReturn(Output& out, const TypePtr& type, const Str out << nl << "return ::std::string();"; break; } + case Builtin::KindValue: case Builtin::KindObject: case Builtin::KindObjectProxy: case Builtin::KindLocalObject: @@ -5448,14 +5607,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") { @@ -5491,14 +5656,30 @@ 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))) + { + 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 + "'"); } _history.insert(s); @@ -5544,3 +5725,3208 @@ Slice::Gen::getHeaderExt(const string& file, const UnitPtr& unit) } return ext; } + +// C++11 visitors +Slice::Gen::Cpp11ObjectDeclVisitor::Cpp11ObjectDeclVisitor(Output& h, Output& c, const string& dllExport) : + H(h), C(c), _dllExport(dllExport) +{ +} + +bool +Slice::Gen::Cpp11ObjectDeclVisitor::visitModuleStart(const ModulePtr& p) +{ + if(!p->hasClassDecls()) + { + return false; + } + + string name = fixKwd(p->name()); + + H << sp << nl << "namespace " << name << nl << '{'; + C << sp << nl << "namespace" << nl << "{"; + return true; +} + +void +Slice::Gen::Cpp11ObjectDeclVisitor::visitModuleEnd(const ModulePtr&) +{ + H << sp << nl << '}'; + C << sp << nl << "}"; +} + +void +Slice::Gen::Cpp11ObjectDeclVisitor::visitClassDecl(const ClassDeclPtr& p) +{ + string t; + if(p->isLocal() && findMetaData("cpp11:type", p, t)) + { + return; + } + string name = fixKwd(p->name()); + string scoped = fixKwd(p->scoped()); + + + if(p->isLocal()) + { + H << sp << nl << "class " << name << ';'; + H << nl << "typedef ::std::shared_ptr< " << name << "> " << p->name() << "Ptr;"; + } + if(p->isInterface()) + { + H << sp << nl << "class " << name << ';'; + H << nl << "typedef ::std::shared_ptr< " << name << "> " << p->name() << "Ptr;"; + } + else // Value class + { + H << sp << nl << "class " << name << ';'; + H << nl << "typedef ::std::shared_ptr< " << name << "> " << p->name() << "Ptr;"; + H << nl << _dllExport << "void __patch(" << p->name() << "Ptr&, const ::Ice::ValuePtr&);"; + } +} + +void +Slice::Gen::Cpp11ObjectDeclVisitor::visitOperation(const OperationPtr& p) +{ + ClassDefPtr cl = ClassDefPtr::dynamicCast(p->container()); + if(cl && !cl->isLocal()) + { + string flatName = p->flattenedScope() + p->name() + "_name"; + C << sp << nl << "const ::std::string " << flatName << " = \"" << p->name() << "\";"; + } +} + +Slice::Gen::Cpp11TypesVisitor::Cpp11TypesVisitor(Output& h, Output& c, const string& dllExport, bool stream) : + H(h), C(c), _dllExport(dllExport), _stream(stream), _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(); + bool hasDefaultValues = p->hasDefaultValues(); + + vector<string> params; + vector<string> allTypes; + vector<string> allParamDecls; + vector<string> baseParams; + + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + params.push_back(fixKwd((*q)->name())); + } + + for(DataMemberList::const_iterator q = allDataMembers.begin(); q != allDataMembers.end(); ++q) + { + string typeName = inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring); + allTypes.push_back(typeName); + allParamDecls.push_back(typeName + " __ice_" + fixKwd((*q)->name())); + } + + if(base) + { + DataMemberList baseDataMembers = base->allDataMembers(); + for(DataMemberList::const_iterator q = baseDataMembers.begin(); q != baseDataMembers.end(); ++q) + { + baseParams.push_back("__ice_" + fixKwd((*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(); + + H << sp << nl << name << spar; + if(p->isLocal()) + { + H << "const char*" << "int"; + } + H << epar; + if(!p->isLocal() && !hasDefaultValues) + { + H << " {}"; + } + else + { + H << ';'; + } + if(!allTypes.empty()) + { + H << nl; + if(!p->isLocal() && allTypes.size() == 1) + { + H << "explicit "; + } + H << name << spar; + if(p->isLocal()) + { + H << "const char*" << "int"; + } + H << allTypes << epar << ';'; + } + H << nl << "virtual ~" << name << "() throw();"; + H << sp; + + + if(!p->isLocal()) + { + string initName = p->flattenedScope() + p->name() + "_init"; + + C << sp << nl << "namespace"; + C << nl << "{"; + + C << sp << nl << "const ::IceInternal::DefaultUserExceptionFactoryInit< " << scoped << "> " + << initName << "(\"" << p->scoped() << "\");"; + + C << sp << nl << "}"; + } + + if(p->isLocal()) + { + C << sp << nl << scoped.substr(2) << "::" << name << spar << "const char* __file" << "int __line" << epar + << " :"; + C.inc(); + emitUpcall(base, "(__file, __line)", true); + if(p->hasDefaultValues()) + { + C << ", "; + writeDataMemberInitializers(C, dataMembers, _useWstring); + } + C.dec(); + C << sb; + C << eb; + } + else if(hasDefaultValues) + { + C << sp << nl << scoped.substr(2) << "::" << name << "() :"; + C.inc(); + writeDataMemberInitializers(C, dataMembers, _useWstring); + C.dec(); + C << sb; + C << eb; + } + + if(!allTypes.empty()) + { + C << sp << nl; + C << scoped.substr(2) << "::" << name << spar; + if(p->isLocal()) + { + C << "const char* __file" << "int __line"; + } + C << allParamDecls << epar; + if(p->isLocal() || !baseParams.empty() || !params.empty()) + { + C << " :"; + C.inc(); + string upcall; + if(!allParamDecls.empty()) + { + upcall = "("; + if(p->isLocal()) + { + upcall += "__file, __line"; + } + for(vector<string>::const_iterator pi = baseParams.begin(); pi != baseParams.end(); ++pi) + { + if(p->isLocal() || pi != baseParams.begin()) + { + upcall += ", "; + } + upcall += *pi; + } + upcall += ")"; + } + if(!params.empty()) + { + upcall += ","; + } + emitUpcall(base, upcall, p->isLocal()); + } + for(vector<string>::const_iterator pi = params.begin(); pi != params.end(); ++pi) + { + if(pi != params.begin()) + { + C << ","; + } + C << nl << *pi << "(__ice_" << *pi << ')'; + } + if(p->isLocal() || !baseParams.empty() || !params.empty()) + { + C.dec(); + } + C << sb; + C << eb; + } + + C << sp << nl; + C << scoped.substr(2) << "::~" << name << "() throw()"; + C << sb; + C << eb; + + H << nl << "virtual ::std::string ice_name() const;"; + C << sp << nl << "::std::string" << nl << scoped.substr(2) << "::ice_name() const"; + C << sb; + C << nl << "return \"" << p->scoped().substr(2) << "\";"; + 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 " << name << "* ice_clone() const;"; + C << sp << nl << scoped.substr(2) << "*" << nl << scoped.substr(2) << "::ice_clone() const"; + C << sb; + C << nl << "return new " << name << "(*this);"; + C << eb; + + 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"); + + if(preserved && !basePreserved) + { + H << sp << nl << "virtual void __write(::IceInternal::BasicStream*) const;"; + H << nl << "virtual void __read(::IceInternal::BasicStream*);"; + + if(_stream) + { + H << nl << "virtual void __write(const ::Ice::OutputStreamPtr&) const;"; + H << nl << "virtual void __read(const ::Ice::InputStreamPtr&);"; + } + else + { + string baseName = base ? fixKwd(base->scoped()) : string("::Ice::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*);"; + + 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;"; + } + + if(preserved && !basePreserved) + { + + H << sp << nl << "::Ice::SlicedDataPtr __slicedData;"; + + C << sp << nl << "void" << nl << scoped.substr(2) << "::__write(::IceInternal::BasicStream* __os) const"; + C << sb; + C << nl << "__os->startWriteException(__slicedData);"; + C << nl << "__writeImpl(__os);"; + C << nl << "__os->endWriteException();"; + C << eb; + + C << sp << nl << "void" << nl << scoped.substr(2) << "::__read(::IceInternal::BasicStream* __is)"; + C << sb; + C << nl << "__is->startReadException();"; + C << nl << "__readImpl(__is);"; + C << nl << "__slicedData = __is->endReadException(true);"; + C << eb; + } + + C << sp << nl << "void" << nl << scoped.substr(2) << "::__writeImpl(::IceInternal::BasicStream* __os) const"; + C << sb; + C << nl << "__os->startWriteSlice(\"" << p->scoped() << "\", -1, " << (!base ? "true" : "false") << ");"; + writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), true); + C << nl << "__os->endWriteSlice();"; + if(base) + { + emitUpcall(base, "::__writeImpl(__os);"); + } + C << eb; + + C << sp << nl << "void" << nl << scoped.substr(2) << "::__readImpl(::IceInternal::BasicStream* __is)"; + C << sb; + C << nl << "__is->startReadSlice();"; + writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), false); + C << nl << "__is->endReadSlice();"; + 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. + // 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(); + string s = typeToString(type, p->typeMetaData(), _useWstring, 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()); + + if(dictType.empty()) + { + // + // A default std::map dictionary + // + + TypePtr keyType = p->keyType(); + TypePtr valueType = p->valueType(); + string ks = typeToString(keyType, p->keyMetaData(), _useWstring); + if(ks[0] == ':') + { + ks.insert(0, " "); + } + string vs = typeToString(valueType, p->valueMetaData(), _useWstring); + + H << sp << nl << "typedef ::std::map<" << ks << ", " << vs << "> " << name << ';'; + } + else + { + // + // A custom dictionary + // + H << sp << nl << "typedef " << dictType << ' ' << name << ';'; + } +} + +Slice::Gen::Cpp11ProxyDeclVisitor::Cpp11ProxyDeclVisitor(Output& h, Output&, const string& dllExport) : + H(h), _dllExport(dllExport) +{ +} + +bool +Slice::Gen::Cpp11ProxyDeclVisitor::visitUnitStart(const UnitPtr& p) +{ + if(!p->hasNonLocalClassDecls()) + { + return false; + } + return true; +} + +void +Slice::Gen::Cpp11ProxyDeclVisitor::visitUnitEnd(const UnitPtr&) +{ +} + +bool +Slice::Gen::Cpp11ProxyDeclVisitor::visitModuleStart(const ModulePtr& p) +{ + if(!p->hasNonLocalClassDecls()) + { + return false; + } + H << sp << nl << "namespace " << fixKwd(p->name()) << nl << '{'; + return true; +} + +void +Slice::Gen::Cpp11ProxyDeclVisitor::visitModuleEnd(const ModulePtr&) +{ + H << sp << nl << '}'; +} + +void +Slice::Gen::Cpp11ProxyDeclVisitor::visitClassDecl(const ClassDeclPtr& p) +{ + if(!p->isLocal()) + { + string name = fixKwd(p->name()); + string scoped = fixKwd(p->scoped()); + + 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::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); + + string name = fixKwd(p->name()); + + H << sp << nl << "namespace " << 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 : "; + if(bases.empty() || (base && base->allOperations().empty())) + { + H << "virtual public ::Ice::ObjectPrx"; + } + else + { + H.useCurrentPosAsIndent(); + ClassList::const_iterator q = bases.begin(); + while(q != bases.end()) + { + H << "virtual public " << fixKwd((*q)->scoped() + "Prx"); + if(++q != bases.end()) + { + H << ',' << nl; + } + } + H.restoreIndent(); + } + + H << sb; + H.dec(); + H << nl << "public:"; + H.inc(); + return true; +} + +void +Slice::Gen::Cpp11ProxyVisitor::visitClassDefEnd(const ClassDefPtr& p) +{ + // + // "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! + // + + string prx = fixKwd(p->name() + "Prx"); + + H << nl << "::std::shared_ptr<" << prx << "> ice_context(const ::Ice::Context& __context) const"; + H << sb; + H << nl << "return ::std::dynamic_pointer_cast<" << prx << ">(Ice::ObjectPrx::ice_context(__context));"; + H << eb; + + // + // No facet! + // + + H << nl << "::std::shared_ptr<" << prx << "> ice_adapterId(const ::std::string& __id) const"; + H << sb; + H << nl << "return ::std::dynamic_pointer_cast<" << prx << ">(::Ice::ObjectPrx::ice_adapterId(__id));"; + H << eb; + + H << nl << "::std::shared_ptr<" << prx << "> ice_endpoints(const ::Ice::EndpointSeq& __endpoints) const"; + H << sb; + H << nl << "return ::std::dynamic_pointer_cast<" << prx << ">(::Ice::ObjectPrx::ice_endpoints(__endpoints));"; + H << eb; + + H << nl << "::std::shared_ptr<" << prx << "> ice_locatorCacheTimeout(int __timeout) const"; + H << sb; + H << nl << "return ::std::dynamic_pointer_cast<" << prx << ">(::Ice::ObjectPrx::ice_locatorCacheTimeout(__timeout));"; + H << eb; + + H << nl << "::std::shared_ptr<" << prx << "> ice_connectionCached(bool __cached) const"; + H << sb; + H << nl << "return ::std::dynamic_pointer_cast<" << prx << ">(::Ice::ObjectPrx::ice_connectionCached(__cached));"; + H << eb; + + H << nl << "::std::shared_ptr<" << prx << "> ice_endpointSelection(::Ice::EndpointSelectionType __est) const"; + H << sb; + H << nl << "return ::std::dynamic_pointer_cast<" << prx << ">(::Ice::ObjectPrx::ice_endpointSelection(__est));"; + H << eb; + + H << nl << "::std::shared_ptr<" << prx << "> ice_secure(bool __secure) const"; + H << sb; + H << nl << "return ::std::dynamic_pointer_cast<" << prx << ">(::Ice::ObjectPrx::ice_secure(__secure));"; + H << eb; + + H << nl << "::std::shared_ptr<" << prx << "> ice_preferSecure(bool __preferSecure) const"; + H << sb; + H << nl << "return ::std::dynamic_pointer_cast<" << prx << ">(::Ice::ObjectPrx::ice_preferSecure(__preferSecure));"; + H << eb; + + H << nl << "::std::shared_ptr<" << prx << "> ice_router(const ::Ice::RouterPrxPtr& __router) const"; + H << sb; + H << nl << "return ::std::dynamic_pointer_cast<" << prx << ">(::Ice::ObjectPrx::ice_router(__router));"; + H << eb; + + H << nl << "::std::shared_ptr<" << prx << "> ice_locator(const ::Ice::LocatorPrxPtr& __locator) const"; + H << sb; + H << nl << "return ::std::dynamic_pointer_cast<" << prx << ">(::Ice::ObjectPrx::ice_locator(__locator));"; + H << eb; + + H << nl << "::std::shared_ptr<" << prx << "> ice_collocationOptimized(bool __co) const"; + H << sb; + H << nl << "return ::std::dynamic_pointer_cast<" << prx << ">(::Ice::ObjectPrx::ice_collocationOptimized(__co));"; + H << eb; + + H << nl << "::std::shared_ptr<" << prx << "> ice_invocationTimeout(int __timeout) const"; + H << sb; + H << nl << "return ::std::dynamic_pointer_cast<" << prx << ">(::Ice::ObjectPrx::ice_invocationTimeout(__timeout));"; + H << eb; + + H << nl << "::std::shared_ptr<" << prx << "> ice_twoway() const"; + H << sb; + H << nl << "return ::std::dynamic_pointer_cast<" << prx << ">(::Ice::ObjectPrx::ice_twoway());"; + H << eb; + + H << nl << "::std::shared_ptr<" << prx << "> ice_oneway() const"; + H << sb; + H << nl << "return ::std::dynamic_pointer_cast<" << prx << ">(::Ice::ObjectPrx::ice_oneway());"; + H << eb; + + H << nl << "::std::shared_ptr<" << prx << "> ice_batchOneway() const"; + H << sb; + H << nl << "return ::std::dynamic_pointer_cast<" << prx << ">(::Ice::ObjectPrx::ice_batchOneway());"; + H << eb; + + H << nl << "::std::shared_ptr<" << prx << "> ice_datagram() const"; + H << sb; + H << nl << "return ::std::dynamic_pointer_cast<" << prx << ">(::Ice::ObjectPrx::ice_datagram());"; + H << eb; + + H << nl << "::std::shared_ptr<" << prx << "> ice_batchDatagram() const"; + H << sb; + H << nl << "return ::std::dynamic_pointer_cast<" << prx << ">(::Ice::ObjectPrx::ice_batchDatagram());"; + H << eb; + + H << nl << "::std::shared_ptr<" << prx << "> ice_compress(bool __compress) const"; + H << sb; + H << nl << "return ::std::dynamic_pointer_cast<" << prx << ">(::Ice::ObjectPrx::ice_compress(__compress));"; + H << eb; + + H << nl << "::std::shared_ptr<" << prx << "> ice_timeout(int __timeout) const"; + H << sb; + H << nl << "return ::std::dynamic_pointer_cast<" << prx << ">(::Ice::ObjectPrx::ice_timeout(__timeout));"; + H << eb; + + H << nl << "::std::shared_ptr<" << prx << "> ice_connectionId(const ::std::string& __id) const"; + H << sb; + H << nl << "return ::std::dynamic_pointer_cast<" << prx << ">(::Ice::ObjectPrx::ice_connectionId(__id));"; + H << eb; + + H << nl << "::std::shared_ptr<" << prx << "> ice_encodingVersion(const ::Ice::EncodingVersion& __v) const"; + H << sb; + H << nl << "return ::std::dynamic_pointer_cast<" << prx << ">(::Ice::ObjectPrx::ice_encodingVersion(__v));"; + H << eb; + + + H << sp; + H << nl << "static const ::std::string& ice_staticId();"; + + H.dec(); + H << sp << nl << "private: "; + H.inc(); + H << nl << "virtual ::std::shared_ptr<::Ice::ObjectPrx> __newInstance() const;"; + + 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; + + C << sp << nl << "::std::shared_ptr<::Ice::ObjectPrx>"; + C << nl << scoped.substr(2) << "::__newInstance() const"; + C << sb; + C << nl << "return ::std::make_shared<" << prx << ">();"; + 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"; + + 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); + + outParams.push_back(*q); + if((*q)->name() == "returnValue") + { + returnValueS = "_returnValue"; + } + } + } + + string scoped = fixKwd(cl->scope() + cl->name() + "Prx" + "::").substr(2); + + string deprecateSymbol = getDeprecateSymbol(p, cl); + H << sp << nl << deprecateSymbol << retS << ' ' << fixKwd(name) << spar << paramsDecl + << "const ::Ice::Context& __ctx = Ice::noExplicitContext" << epar << ";"; + + C << sp; + C << nl << retS; + C << nl << scoped << fixKwd(p->name()) << spar << paramsDecl << "const ::Ice::Context& __ctx" << epar; + C << sb; + C << nl << "::std::promise<" << retS << "> __promise;"; + if(!p->returnsData()) + { + C << nl << "if(ice_isTwoway())"; + C << sb; + } + + C << nl << name << "_async("; + C.useCurrentPosAsIndent(); + for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end();) + { + C << fixKwd(paramPrefix + (*q)->name()) << ","; + if(++q != inParams.end()) + { + C << " "; + } + } + if(!inParams.empty()) + { + C << nl; + } + C << "[&]("; + if(retS != "void") + { + C << retS << " __ret"; + } + if(!outParams.empty()) + { + if(retS != "void") + { + C << ", "; + } + for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end();) + { + C << typeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring, true) + << " " << "__o_" << (*q)->name(); + if(++q != outParams.end()) + { + C << ","; + } + } + } + C << ")"; + C << sb; + if(!outParams.empty()) + { + for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end(); ++q) + { + C << nl << paramPrefix << (*q)->name() << " = "; + bool movable = isMovable((*q)->type()); + if(movable) + { + C << "::std::move("; + } + C << "__o_" << (*q)->name(); + if(movable) + { + C << ")"; + } + C << ";"; + } + } + C << nl << "__promise.set_value("; + if(retS != "void") + { + C << (isMovable(ret) ? "::std::move(__ret)" : "__ret"); + } + C << ");"; + C << eb << ","; + C << nl << "[&](::std::exception_ptr __ex)"; + C << sb; + C << nl << "__promise.set_exception(::std::move(__ex));"; + C << eb << ","; + C << nl << "nullptr, __ctx);"; + C.restoreIndent(); + C << nl; + if(retS != "void") + { + C << "return "; + } + C << "__promise.get_future().get();"; + + if(!p->returnsData()) + { + C << eb; + C << nl << "else if(ice_isOneway() || ice_isDatagram())"; + C << sb; + + C << nl << name << "_async("; + C.useCurrentPosAsIndent(); + for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end();) + { + C << fixKwd(paramPrefix + (*q)->name()) << ","; + if(++q != inParams.end()) + { + C << " "; + } + } + if(!inParams.empty()) + { + C << nl; + } + C << "nullptr,"; + C << nl << "[&](::std::exception_ptr __ex)"; + C << sb; + C << nl << "__promise.set_exception(::std::move(__ex));"; + C << eb << ","; + C << nl << "[&](bool)"; + C << sb; + C << nl << "__promise.set_value();"; + C << eb << ","; + C << nl << "__ctx);"; + C.restoreIndent(); + C << nl << "__promise.get_future().get();"; + + C << eb; + C << nl << "else"; + C << sb; + C << nl << name << "_async("; + for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end(); ++q) + { + C << fixKwd(paramPrefix + (*q)->name()) << ","; + } + C << " nullptr, nullptr, nullptr, __ctx);"; + C << nl << "__promise.set_value();"; + C << eb; + } + + C << eb; + + H << sp; + H << nl << "::std::function<void ()>"; + H << nl << name << "_async("; + H.useCurrentPosAsIndent(); + for(vector<string>::const_iterator i = lambdaParams.begin(); i != lambdaParams.end();) + { + H << *i << ","; + if(++i != lambdaParams.end()) + { + H << " "; + } + } + if(!lambdaParams.empty()) + { + H << nl; + } + H << "::std::function<void ("; + if(retS != "void") + { + H << retS; + if(!lambdaOutParams.empty()) + { + H << ", "; + } + } + for(vector<string>::const_iterator i = lambdaOutParams.begin(); i != lambdaOutParams.end();) + { + H << (*i); + if(++i != lambdaOutParams.end()) + { + H << ", "; + } + } + H << ")>,"; + H << nl << "::std::function<void (::std::exception_ptr)> __exception = nullptr," + << nl << "::std::function<void (bool)> __sent = nullptr," + << nl << "const ::Ice::Context& __ctx = Ice::noExplicitContext);"; + H.restoreIndent(); + + C << sp; + C << nl << "::std::function<void ()>"; + C << nl << scoped << fixKwd(p->name() + "_async") << "("; + C.useCurrentPosAsIndent(); + for(vector<string>::const_iterator i = lambdaParamsDecl.begin(); i != lambdaParamsDecl.end();) + { + C << *i << ","; + if(++i != lambdaParamsDecl.end()) + { + C << " "; + } + } + if(!lambdaParamsDecl.empty()) + { + C << nl; + } + C << "::std::function<void ("; + if(retS != "void") + { + C << retS; + if(!lambdaOutParams.empty()) + { + C << ", "; + } + } + for(vector<string>::const_iterator i = lambdaOutParams.begin(); i != lambdaOutParams.end();) + { + C << (*i); + if(++i != lambdaOutParams.end()) + { + C << ", "; + } + } + C << ")> __response,"; + C << nl << "::std::function<void (::std::exception_ptr)> __exception," + << nl << "::std::function<void (bool)> __sent," + << nl << "const ::Ice::Context& __ctx)"; + C.restoreIndent(); + C << sb; + C << nl << "return ::IceInternal::" << (p->returnsData() ? "Twoway" : "Oneway") << "ClosureCallback::invoke("; + C.inc(); + C << nl << flatName << ", shared_from_this(), " + << operationModeToString(p->sendMode(), true) << ", " + << opFormatTypeToString(p) << ","; + if(inParams.empty()) + { + C << " nullptr,"; + } + else + { + C << nl << "[&](::IceInternal::BasicStream* __os)"; + C << sb; + writeMarshalCode(C, inParams, 0, true, TypeContextInParam); + if(p->sendsClasses(false)) + { + C << nl << "__os->writePendingObjects();"; + } + C << eb << ","; + } + + if(p->returnsData()) + { + if(ret || !outParams.empty()) + { + C << nl << "false" << ","; + C << nl << "[__response = ::std::move(__response)](::IceInternal::BasicStream* __is)"; + C << sb; + writeAllocateCode(C, outParams, p, true, _useWstring | TypeContextAMIEnd | TypeContextReadClosure, true); + writeUnmarshalCode(C, outParams, p, true, _useWstring | TypeContextAMIEnd); + if(p->returnsClasses(false)) + { + C << nl << "__is->readPendingObjects();"; + } + C << nl << "__is->endReadEncaps();"; + C << nl << "if(__response)"; + C << sb; + C << nl << "try"; + C << sb; + C << nl << "__response("; + if(ret) + { + C << (isMovable(ret) ? "::std::move(__ret)" : "__ret"); + if(!outParams.empty()) + { + C << ", "; + } + } + for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end();) + { + string p = fixKwd(paramPrefix + (*q)->name()); + C << (isMovable((*q)->type()) ? ("::std::move(" + p + ")") : p); + if(++q != outParams.end()) + { + C << ","; + } + } + C << ");"; + C << eb; + C << nl << "catch(...)"; + C << sb; + C << nl << "throw std::current_exception();"; + C << eb; + C << eb; + C << eb << ","; + } + else + { + C << nl << "true" << ","; + C << nl << "[__response](::IceInternal::BasicStream*)"; + C << sb; + C << nl << "if(__response)"; + C << sb; + C << nl << "try"; + C << sb; + C << nl << "__response();"; + C << eb; + C << nl << "catch(...)"; + C << sb; + C << nl << "throw std::current_exception();"; + C << eb; + C << eb; + C << eb << ","; + } + + ExceptionList throws = p->throws(); + if(!throws.empty()) + { + 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 + C << nl << "[](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 << ","; + } + else + { + C << nl << "nullptr, "; + } + } + else + { + C << nl << "__response,"; + } + C << nl << "::std::move(__exception), ::std::move(__sent), __ctx);"; + C.dec(); + C << eb; + + string futureT; + + if(retS == "void" && outParams.empty()) + { + futureT = "void"; + } + else if(outParams.empty()) + { + futureT = retS; + } + else if(retS == "void" && outParams.size() == 1) + { + ParamDeclPtr param = outParams.front(); + futureT = typeToString(param->type(), param->optional(), param->getMetaData(), _useWstring, true); + } + else + { + futureT = "Result_" + name; + } + + if(futureT.find("Result_") == 0) + { + // We need to generate a Result_ struct. + H << sp; + H << nl << "struct Result_" << name; + H << sb; + if(retS != "void") + { + H << nl << retS << " " << returnValueS << ";"; + } + for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end(); ++q) + { + H << nl << typeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring, true) + << " " << (*q)->name() << ";"; + } + H << eb << ";"; + } + + H << sp; + H << nl << "template<template<typename> class P = ::std::promise>"; + H << nl << deprecateSymbol << "auto " << name << "_async" << spar << futureParamsDecl + << "const ::Ice::Context& __ctx = Ice::noExplicitContext" << epar; + H.inc(); + H << nl << "-> decltype(::std::declval<P<" << futureT << ">>().get_future())"; + H.dec(); + H << sb; + H << nl << "using Promise = P<" << futureT << ">;"; + H << nl << "auto __promise = ::std::make_shared<Promise>();"; + if(!p->returnsData()) + { + H << nl << "if(ice_isTwoway())"; + H << sb; + } + H << nl << name << "_async("; + H.useCurrentPosAsIndent(); + for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end();) + { + H << fixKwd(paramPrefix + (*q)->name()) << ","; + if(++q != inParams.end()) + { + H << " "; + } + } + if(!inParams.empty()) + { + H << nl; + } + H << "[__promise]("; + + if(retS != "void") + { + H << retS << " __ret"; + if(!lambdaOutParams.empty()) + { + H << ", "; + } + } + for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end();) + { + H << typeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring, true) + << " " << paramPrefix << (*q)->name(); + if(++q != outParams.end()) + { + H << ","; + } + } + H << ")"; + H << sb; + if(retS == "void" && outParams.empty()) + { + H << nl << "__promise->set_value();"; + } + else if(outParams.empty()) + { + H << nl << "__promise->set_value(" << (isMovable(ret) ? "::std::move(__ret)" : "__ret") << ");"; + } + else if(retS == "void" && outParams.size() == 1) + { + H << nl << "__promise->set_value(" << paramPrefix << outParams.front()->name() << ");"; + } + else + { + H << nl << "Result_" << name << " __result;"; + if(retS != "void") + { + H << nl << "__result." << returnValueS << " = " << (isMovable(ret) ? "::std::move(__ret)" : "__ret") << ";"; + } + for(ParamDeclList::const_iterator q = outParams.begin(); q != outParams.end(); ++q) + { + H << nl << "__result." << (*q)->name() << " = " + << (isMovable((*q)->type()) ? ("::std::move(" + paramPrefix + (*q)->name() + ")") : (paramPrefix + (*q)->name())) + << ";"; + } + H << nl << "__promise->set_value(::std::move(__result));"; + } + + H << eb << ","; + H << nl << "[__promise](::std::exception_ptr __ex)"; + H << sb; + H << nl << "__promise->set_exception(::std::move(__ex));"; + H << eb << ","; + H << nl << "nullptr, __ctx);"; + H.restoreIndent(); + + if(!p->returnsData()) + { + H << eb; + H << nl << "else if(ice_isOneway() || ice_isDatagram())"; + H << sb; + + H << nl << name << "_async("; + H.useCurrentPosAsIndent(); + for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end();) + { + H << fixKwd(paramPrefix + (*q)->name()) << ","; + if(++q != inParams.end()) + { + H << " "; + } + } + H << nl << "nullptr,"; + H << nl << "[__promise](::std::exception_ptr __ex)"; + H << sb; + H << nl << "__promise->set_exception(::std::move(__ex));"; + H << eb << ","; + H << nl << "[__promise](bool)"; + H << sb; + H << nl << "__promise->set_value();"; + H << eb << ","; + H << nl << "__ctx);"; + H.restoreIndent(); + + H << eb; + H << nl << "else"; + H << sb; + H << nl << name << "_async("; + for(ParamDeclList::const_iterator q = inParams.begin(); q != inParams.end(); ++q) + { + H << fixKwd(paramPrefix + (*q)->name()) << ","; + } + H << "nullptr, nullptr, nullptr, __ctx);"; + H << eb; + } + + H << nl << "return __promise->get_future();"; + H << eb; +} + + +namespace +{ + +string +enumSizeType(IceUtil::Int64 size) +{ + if(size <= 0xFF) + { + return "char"; + } + else if(size <= 0xFFFF) + { + return "short"; + } + else if(size <= 0xFFFFFFFF) + { + return "int"; + } + else + { + return "long long int"; + } +} + +}; + +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) + { + H << " : " << enumSizeType(p->maxValue()); + } + 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, + bool stream) : + H(h), + C(c), + _dllExport(dllExport), + _stream(stream), + _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 << ';'; +} + +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, + bool stream) : + Cpp11ObjectVisitor(h, c, dllExport, stream) +{ +} + +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; + } + string t; + if(findMetaData("cpp11:type:", p->getMetaData(), t)) + { + H << sp << "typedef " << t << " " << fixKwd(p->name()) << ";"; + 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 " << p->name() << "Ptr 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); + H.dec(); + H << sb; + H << eb; + } + else + { + H << sp << nl << name << "()"; + H << sb << eb; + } + + emitOneShotConstructor(p); + H << sp; + } + 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;"; + + if(!_doneStaticSymbol) + { + H << sp << nl << "friend class " << p->name() << "__staticInit;"; + } + } + + H << eb << ';'; + + if(!p->isAbstract() && !_doneStaticSymbol) + { + // + // We need an instance here to trigger initialization if the implementation is in a shared 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. + // + 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;"; + } +} + +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()); + + TypePtr ret = p->returnType(); + string retS = returnTypeToString(ret, p->returnIsOptional(), p->getMetaData(), _useWstring, 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(), _useWstring, true); + } + else + { + inParams.push_back(*q); + typeString = inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring, true); + } + + if(q != paramList.begin()) + { + params += ", "; + paramsDecl += ", "; + args += ", "; + } + + params += typeString; + paramsDecl += typeString; + paramsDecl += ' '; + paramsDecl += paramName; + args += paramName; + + if(isOutParam) + { + outDecls.push_back(inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring, true)); + } + } + + params += ')'; + paramsDecl += ')'; + args += ')'; + + bool isConst = (p->mode() == Operation::Nonmutating) || p->hasMetaData("cpp:const"); + + string deprecateSymbol = getDeprecateSymbol(p, cl); + + H << sp; + H << nl << deprecateSymbol << "virtual " << retS << ' ' << fixKwd(name) << params + << (isConst ? " const" : "") << " = 0;"; + + if(cl->hasMetaData("async") || p->hasMetaData("async")) + { + 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 = outputTypeToString((*r)->type(), (*r)->optional(), metaData, + _useWstring | TypeContextAMIEnd, true); + } + else + { + typeString = inputTypeToString((*r)->type(), (*r)->optional(), metaData, _useWstring, true); + } + + if(!(*r)->isOutParam()) + { + paramsDeclAMI.push_back(typeString + ' ' + paramName); + } + else + { + outParamsDeclAMI.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 ("; + for(vector<string>::const_iterator i = outParamsDeclAMI.begin(); i != outParamsDeclAMI.end();) + { + H << *i << ","; + if(++i != outParamsDeclAMI.end()) + { + H << " "; + } + } + H << ")>,"; + H << nl << "::std::function<void (::std::exception_ptr)> exception = nullptr,"; + H << nl << "::std::function<void (bool)> sent = nullptr) = 0;"; + H.restoreIndent(); + } +} + +Slice::Gen::Cpp11InterfaceVisitor::Cpp11InterfaceVisitor(::IceUtilInternal::Output& h, + ::IceUtilInternal::Output& c, + const std::string& dllExport, + bool stream) : + Cpp11ObjectVisitor(h, c, dllExport, stream) +{ +} + +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 << "virtual public ::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 << "virtual public " << 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; +#if defined(__IBMCPP__) && defined(NDEBUG) + // + // VisualAge C++ 6.0 does not see that ClassDef is a Contained, + // when inlining is on. The code below issues a warning: better + // than an error! + // + transform(allBases.begin(), allBases.end(), back_inserter(ids), ::IceUtil::constMemFun<string,ClassDef>(&Contained::scoped)); +#else + transform(allBases.begin(), allBases.end(), back_inserter(ids), ::IceUtil::constMemFun(&Contained::scoped)); +#endif + 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" + << "(const ::std::string&, const ::Ice::Current& = ::Ice::Current()) const;"; + H << nl << "virtual ::std::vector< ::std::string> ice_ids" + << "(const ::Ice::Current& = ::Ice::Current()) const;"; + H << nl << "virtual const ::std::string& ice_id(const ::Ice::Current& = ::Ice::Current()) const;"; + H << nl << "static const ::std::string& ice_staticId();"; + + string flatName = p->flattenedScope() + p->name() + (p->isInterface() ? "" : "Disp") + "_ids"; + + C << sp << nl << "namespace"; + C << nl << "{"; + C << nl << "const ::std::string " << flatName << '[' << ids.size() << "] ="; + C << sb; + + for(StringList::const_iterator r = ids.begin(); r != ids.end();) + { + C << nl << '"' << *r << '"'; + if(++r != ids.end()) + { + C << ','; + } + } + + C << eb << ';'; + C << sp << nl << "}"; + + C << sp; + C << nl << "bool" << nl << scoped.substr(2) + << "::ice_isA(const ::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 << "static const ::std::string typeId = \"" << *scopedIter << "\";"; + C << nl << "return typeId;"; + C << eb; + return true; +} + +void +Slice::Gen::Cpp11InterfaceVisitor::visitClassDefEnd(const ClassDefPtr& p) +{ + string suffix = p->isInterface() ? "" : "Disp"; + string scoped = fixKwd(p->scope() + p->name() + suffix); + + string scope = fixKwd(p->scope()); + string name = fixKwd(p->name() + suffix); + ClassList bases = p->bases(); + ClassDefPtr base; + if(!bases.empty() && !bases.front()->isInterface()) + { + base = bases.front(); + } + + OperationList allOps = p->allOperations(); + if(!allOps.empty()) + { + StringList allOpNames; +#if defined(__IBMCPP__) && defined(NDEBUG) +// +// See comment for transform above +// + transform(allOps.begin(), allOps.end(), back_inserter(allOpNames), + ::IceUtil::constMemFun<string,Operation>(&Contained::name)); +#else + transform(allOps.begin(), allOps.end(), back_inserter(allOpNames), + ::IceUtil::constMemFun(&Contained::name)); +#endif + allOpNames.push_back("ice_id"); + allOpNames.push_back("ice_ids"); + allOpNames.push_back("ice_isA"); + allOpNames.push_back("ice_ping"); + allOpNames.sort(); + allOpNames.unique(); + + H << sp; + H << nl + << "virtual ::Ice::DispatchStatus __dispatch(::IceInternal::Incoming&, const ::Ice::Current&);"; + + string flatName = p->flattenedScope() + name + "_all"; + C << sp << nl << "namespace"; + C << nl << "{"; + C << nl << "const ::std::string " << flatName << "[] ="; + C << sb; + + for(StringList::const_iterator q = allOpNames.begin(); q != allOpNames.end();) + { + C << nl << '"' << *q << '"'; + if(++q != allOpNames.end()) + { + C << ','; + } + } + C << eb << ';'; + C << sp << nl << "}"; + C << sp; + C << nl << "::Ice::DispatchStatus" << nl << scoped.substr(2) + << "::__dispatch(::IceInternal::Incoming& in, const ::Ice::Current& current)"; + C << sb; + + C << nl << "::std::pair< const ::std::string*, const ::std::string*> r = " + << "::std::equal_range(" << flatName << ", " << flatName << " + " << allOpNames.size() + << ", current.operation);"; + C << nl << "if(r.first == r.second)"; + C << sb; + C << nl << "throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, " + << "current.facet, current.operation);"; + C << eb; + C << sp; + C << nl << "switch(r.first - " << flatName << ')'; + C << sb; + int i = 0; + for(StringList::const_iterator q = allOpNames.begin(); q != allOpNames.end(); ++q) + { + C << nl << "case " << i++ << ':'; + C << sb; + C << nl << "return ___" << *q << "(in, current);"; + C << eb; + } + C << eb; + C << sp; + C << nl << "assert(false);"; + C << nl << "throw ::Ice::OperationNotExistException(__FILE__, __LINE__, current.id, " + << "current.facet, current.operation);"; + C << eb; + + // + // Check if we need to generate ice_operationAttributes() + // + map<string, int> attributesMap; + for(OperationList::iterator r = allOps.begin(); r != allOps.end(); ++r) + { + int attributes = (*r)->attributes(); + if(attributes != 0) + { + attributesMap.insert(map<string, int>::value_type((*r)->name(), attributes)); + } + } + } + + 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 = inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring, true); + } + + if(q != paramList.begin()) + { + params += ", "; + paramsDecl += ", "; + args += ", "; + } + + params += typeString; + paramsDecl += typeString; + paramsDecl += ' '; + paramsDecl += paramName; + args += paramName; + } + + if(!paramList.empty()) + { + params += ", "; + paramsDecl += ", "; + args += ", "; + } + + params += "const ::Ice::Current& = ::Ice::Current())"; + paramsDecl += "const ::Ice::Current& __current)"; + args += "__current)"; + + for(ParamDeclList::iterator q = inParams.begin(); q != inParams.end(); ++q) + { + if(q != inParams.begin()) + { + paramsAMD += ", "; + argsAMD += ", "; + } + paramsAMD += inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring, true); + 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 paramName = fixKwd(string(paramPrefix) + (*q)->name()); + string typeString = inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), _useWstring, true); + responseParams += typeString; + responseParamsDecl += typeString + " " + paramName; + } + + bool isConst = (p->mode() == Operation::Nonmutating) || p->hasMetaData("cpp: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 ? " const" : "") << " = 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 (const ::std::exception_ptr&)>, const Ice::Current&)" + << (isConst ? " const" : "") << " = 0;"; + H.restoreIndent(); + } + + H << sp; + H << nl << "::Ice::DispatchStatus ___" << name << "(::IceInternal::Incoming&, const ::Ice::Current&)" + << (isConst ? " const" : "") << ';'; + + C << sp; + C << nl << "::Ice::DispatchStatus" << nl << scope.substr(2) << "___" << name << "(::IceInternal::Incoming& __inS" + << ", const ::Ice::Current& __current)" << (isConst ? " const" : ""); + C << sb; + C << nl << "__checkMode(" << operationModeToString(p->mode(), true) << ", __current.mode);"; + + if(!inParams.empty()) + { + C << nl << "::IceInternal::BasicStream* __is = __inS.startReadParams();"; + writeAllocateCode(C, inParams, 0, true, _useWstring | TypeContextInParam | TypeContextReadClosure, 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 = ::std::make_shared<::IceInternal::IncomingAsync>(__inS);"; + C << nl << "auto __exception = [inS](const ::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, + bool stream) : + Cpp11ObjectVisitor(h, c, dllExport, stream) +{ +} + +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 << " : "; + H.useCurrentPosAsIndent(); + if(!base || (base && base->isInterface())) + { + H << "public ::Ice::Value"; + } + else + { + H << "public " << fixKwd(base->scoped()); + } + + 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 " << p->name() << "Ptr 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->hasDefaultValues()) + { + H << sp << nl << name << "() :"; + H.inc(); + writeDataMemberInitializers(H, dataMembers, _useWstring); + H.dec(); + H << sb; + H << eb; + } + else + { + H << sp << nl << name << "()"; + H << sb << eb; + } + + emitOneShotConstructor(p); + H << sp; + H << nl << "virtual ::Ice::ValuePtr ice_clone() const;"; + 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()); + 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(::IceInternal::BasicStream*) const;"; + H << nl << "virtual void __read(::IceInternal::BasicStream*);"; + } + + H.dec(); + H << sp << nl << "protected:"; + H.inc(); + + H << nl << "virtual void __writeImpl(::IceInternal::BasicStream*) const;"; + H << nl << "virtual void __readImpl(::IceInternal::BasicStream*);"; + + if(preserved && !basePreserved) + { + C << sp; + C << nl << "void" << nl << scoped.substr(2) + << "::__write(::IceInternal::BasicStream* __os) const"; + C << sb; + C << nl << "__os->startWriteObject(__slicedData);"; + C << nl << "__writeImpl(__os);"; + C << nl << "__os->endWriteObject();"; + C << eb; + + C << sp; + C << nl << "void" << nl << scoped.substr(2) << "::__read(::IceInternal::BasicStream* __is)"; + C << sb; + C << nl << "__is->startReadObject();"; + C << nl << "__readImpl(__is);"; + C << nl << "__slicedData = __is->endReadObject(true);"; + C << eb; + } + + C << sp; + C << nl << "void" << nl << scoped.substr(2) + << "::__writeImpl(::IceInternal::BasicStream* __os) const"; + C << sb; + C << nl << "__os->startWriteSlice(ice_staticId(), " << p->compactId() << (!base ? ", true" : ", false") << ");"; + writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), true); + C << nl << "__os->endWriteSlice();"; + if(base) + { + emitUpcall(base, "::__writeImpl(__os);"); + } + C << eb; + + C << sp; + C << nl << "void" << nl << scoped.substr(2) << "::__readImpl(::IceInternal::BasicStream* __is)"; + C << sb; + C << nl << "__is->startReadSlice();"; + writeMarshalUnmarshalDataMembers(C, p->dataMembers(), p->orderedOptionalDataMembers(), false); + C << nl << "__is->endReadSlice();"; + if(base) + { + emitUpcall(base, "::__readImpl(__is);"); + } + C << eb; + + C << sp; + C << nl << "::Ice::ValuePtr"; + C << nl << scoped.substr(2) << "::ice_clone() const"; + C << sb; + C << nl << "return ::std::make_shared<" << scoped << ">(*this);"; + C << eb; + + C << sp; + C << nl << "const ::std::string&" << nl << scoped.substr(2) << "::ice_staticId()"; + C << sb; + C << nl << "static const ::std::string typeId = \"" << p->scoped() << "\";"; + C << nl << "return typeId;"; + C << eb; + + C << sp << nl << "namespace"; + C << nl << "{"; + + string initName = p->flattenedScope() + p->name() + "_init"; + C << sp << nl << "const ::IceInternal::DefaultObjectFactoryInit< " << scoped << "> " + << initName << "(\"" << p->scoped() << "\");"; + + if(p->compactId() >= 0) + { + string initName = p->flattenedScope() + p->name() + "_compactIdInit"; + C << sp << nl << "const ::IceInternal::CompactIdInit " + << initName << "(\"" << p->scoped() << "\", " << p->compactId() << ");"; + } + C << nl << "}"; + + // + // 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(!_doneStaticSymbol) + { + H << sp << nl << "friend class " << p->name() << "__staticInit;"; + } + + if(preserved && !basePreserved) + { + if(!inProtected) + { + H.dec(); + H << sp << nl << "protected:"; + H.inc(); + inProtected = true; + } + H << sp << nl << "::Ice::SlicedDataPtr __slicedData;"; + } + + H << eb << ';'; + + if(!_doneStaticSymbol) + { + // + // We need an instance here to trigger initialization if the implementation is in a shared 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. + // + 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;"; + } + + _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& p, bool virtualInheritance, bool direct) +{ + DataMemberList allDataMembers = p->allDataMembers(); + if(allDataMembers.empty()) + { + return false; + } + + ClassList bases = p->bases(); + if(!bases.empty() && !bases.front()->isInterface()) + { + if(emitVirtualBaseInitializers(bases.front(), false, false)) + { + H << ','; + } + } + + // + // Do not call non direct base classes constructor if not using virtual inheritance. + // + if(!direct && !virtualInheritance) + { + return false; + } + + string upcall = "("; + for(DataMemberList::const_iterator q = allDataMembers.begin(); q != allDataMembers.end(); ++q) + { + if(q != allDataMembers.begin()) + { + upcall += ", "; + } + upcall += "__ice_" + (*q)->name(); + } + upcall += ")"; + + H << nl << fixKwd(p->scoped()) << 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); + 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(); + ClassDefPtr base; + + if(!bases.empty() && !bases.front()->isInterface()) + { + if(emitVirtualBaseInitializers(bases.front(), false, true)) + { + 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()); + H << memberName << '(' << "__ice_" << (*q)->name() << ')'; + } + + H.dec(); + H << sb; + H << eb; + } +} + +Slice::Gen::Cpp11StreamVisitor::Cpp11StreamVisitor(Output& h, Output& c, const string& dllExport) : + H(h), + C(c), + _dllExport(dllExport) +{ +} + +bool +Slice::Gen::Cpp11StreamVisitor::visitModuleStart(const ModulePtr& m) +{ + if(!m->hasNonLocalContained(Contained::ContainedTypeStruct) && + !m->hasNonLocalContained(Contained::ContainedTypeEnum) && + !m->hasNonLocalContained(Contained::ContainedTypeException)) + { + return false; + } + + if(UnitPtr::dynamicCast(m->container())) + { + // + // Only emit this for the top-level module. + // + H << sp; + H << nl << "namespace Ice" << nl << '{'; + + 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 << '}'; + C << nl << '}'; + } +} + +bool +Slice::Gen::Cpp11StreamVisitor::visitExceptionStart(const ExceptionPtr&) +{ + return false; +} + +bool +Slice::Gen::Cpp11StreamVisitor::visitStructStart(const StructPtr& 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 = StreamHelperCategoryStruct;"; + + H << nl << "static const int minWireSize = " << p->minWireSize() << ";"; + if(p->isVariableLength()) + { + H << nl << "static const bool fixedLength = false;"; + } + else + { + H << nl << "static const bool fixedLength = 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 << ", ::IceInternal::BasicStream>;"; + H << nl << "template struct " << _dllExport << "StreamReader< " << scoped << ", ::IceInternal::BasicStream>;"; + H << nl << "#endif" << nl; + + // + // The instantations: + // + C << nl << "#if defined(ICE_HAS_DECLSPEC_IMPORT_EXPORT) && !defined(ICE_STATIC_LIBS)"; + C << nl << "template struct " << _dllExport << "StreamWriter< " << scoped << ", ::IceInternal::BasicStream>;"; + C << nl << "template struct " << _dllExport << "StreamReader< " << scoped << ", ::IceInternal::BasicStream>;"; + 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::Cpp11InterfaceTraitsVisitor::Cpp11InterfaceTraitsVisitor(Output& h, Output& c, const string& dllExport) : + H(h), C(c), _dllExport(dllExport) +{ +} + +bool +Slice::Gen::Cpp11InterfaceTraitsVisitor::visitUnitStart(const UnitPtr& p) +{ + if(!p->hasNonLocalClassDecls()) + { + return false; + } + + H << sp << nl << "namespace Ice" << nl << '{'; + + return true; +} + +void +Slice::Gen::Cpp11InterfaceTraitsVisitor::visitUnitEnd(const UnitPtr&) +{ + H << sp << nl << '}'; +} + +bool +Slice::Gen::Cpp11InterfaceTraitsVisitor::visitClassDefStart(const ClassDefPtr& p) +{ + if(!p->isInterface() || p->isLocal()) + { + return false; + } + H << sp; + H << nl << "template<>"; + H << nl << "struct InterfaceTraits<" << fixKwd(p->scoped()) << ">"; + H << sb; + H << nl << "static const std::string staticId;"; + H << nl << "static const int compactId = " << p->compactId() << ";"; + H << eb << ";"; + + C << sp; + C << nl << "const std::string Ice::InterfaceTraits<" << fixKwd(p->scoped()) << ">::staticId = \"" << p->scoped() << "\";"; + return true; +} diff --git a/cpp/src/slice2cpp/Gen.h b/cpp/src/slice2cpp/Gen.h index ea122709a6e..1877ff01d88 100644 --- a/cpp/src/slice2cpp/Gen.h +++ b/cpp/src/slice2cpp/Gen.h @@ -36,7 +36,7 @@ public: void generate(const UnitPtr&); void closeOutput(); - + static int setUseWstring(ContainedPtr, std::list<int>&, int); static int resetUseWstring(std::list<int>&); @@ -321,7 +321,7 @@ private: int _useWstring; std::list<int> _useWstringHist; }; - + class StreamVisitor : private ::IceUtil::noncopyable, public ParserVisitor { public: @@ -340,6 +340,253 @@ private: ::IceUtilInternal::Output& C; std::string _dllExport; }; + // + // C++11 Visitors + // + class Cpp11ObjectDeclVisitor : private ::IceUtil::noncopyable, public ParserVisitor + { + public: + + Cpp11ObjectDeclVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&, const std::string&); + + virtual bool visitModuleStart(const ModulePtr&); + virtual void visitModuleEnd(const ModulePtr&); + virtual void visitClassDecl(const ClassDeclPtr&); + virtual void visitOperation(const OperationPtr&); + + private: + + ::IceUtilInternal::Output& H; + ::IceUtilInternal::Output& C; + + std::string _dllExport; + }; + + class Cpp11TypesVisitor : private ::IceUtil::noncopyable, public ParserVisitor + { + public: + + Cpp11TypesVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&, const std::string&, bool); + + virtual bool visitModuleStart(const ModulePtr&); + virtual void visitModuleEnd(const ModulePtr&); + virtual bool visitClassDefStart(const ClassDefPtr&); + virtual bool visitExceptionStart(const ExceptionPtr&); + virtual void visitExceptionEnd(const ExceptionPtr&); + virtual bool visitStructStart(const StructPtr&); + virtual void visitStructEnd(const StructPtr&); + virtual void visitSequence(const SequencePtr&); + virtual void visitDictionary(const DictionaryPtr&); + virtual void visitEnum(const EnumPtr&); + virtual void visitConst(const ConstPtr&); + virtual void visitDataMember(const DataMemberPtr&); + + private: + + void emitUpcall(const ExceptionPtr&, const std::string&, bool = false); + + ::IceUtilInternal::Output& H; + ::IceUtilInternal::Output& C; + + std::string _dllExport; + bool _stream; + bool _doneStaticSymbol; + int _useWstring; + std::list<int> _useWstringHist; + }; + + class Cpp11ProxyVisitor : private ::IceUtil::noncopyable, public ParserVisitor + { + public: + + Cpp11ProxyVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&, const std::string&); + + virtual bool visitUnitStart(const UnitPtr&); + virtual void visitUnitEnd(const UnitPtr&); + virtual bool visitModuleStart(const ModulePtr&); + virtual void visitModuleEnd(const ModulePtr&); + virtual bool visitClassDefStart(const ClassDefPtr&); + virtual void visitClassDefEnd(const ClassDefPtr&); + virtual void visitOperation(const OperationPtr&); + + private: + + ::IceUtilInternal::Output& H; + ::IceUtilInternal::Output& C; + + std::string _dllExport; + int _useWstring; + std::list<int> _useWstringHist; + }; + + class Cpp11ProxyDeclVisitor : private ::IceUtil::noncopyable, public ParserVisitor + { + public: + + Cpp11ProxyDeclVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&, const std::string&); + + virtual bool visitUnitStart(const UnitPtr&); + virtual void visitUnitEnd(const UnitPtr&); + virtual bool visitModuleStart(const ModulePtr&); + virtual void visitModuleEnd(const ModulePtr&); + virtual void visitClassDecl(const ClassDeclPtr&); + + private: + + ::IceUtilInternal::Output& H; + + std::string _dllExport; + }; + + class Cpp11ObjectVisitor : public ParserVisitor + { + public: + + Cpp11ObjectVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&, const std::string&, bool); + + protected: + + bool emitVirtualBaseInitializers(const ClassDefPtr&, bool, bool); + void emitOneShotConstructor(const ClassDefPtr&); + void emitDataMember(const DataMemberPtr&); + + ::IceUtilInternal::Output& H; + ::IceUtilInternal::Output& C; + + std::string _dllExport; + bool _stream; + bool _doneStaticSymbol; + int _useWstring; + std::list<int> _useWstringHist; + }; + + class Cpp11LocalObjectVisitor : private ::IceUtil::noncopyable, public Cpp11ObjectVisitor + { + public: + + Cpp11LocalObjectVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&, const std::string&, bool); + + virtual bool visitModuleStart(const ModulePtr&); + virtual void visitModuleEnd(const ModulePtr&); + virtual bool visitClassDefStart(const ClassDefPtr&); + virtual void visitClassDefEnd(const ClassDefPtr&); + virtual bool visitExceptionStart(const ExceptionPtr&); + virtual bool visitStructStart(const StructPtr&); + virtual void visitOperation(const OperationPtr&); + }; + + class Cpp11InterfaceVisitor : private ::IceUtil::noncopyable, public Cpp11ObjectVisitor + { + public: + + Cpp11InterfaceVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&, const std::string&, bool); + + virtual bool visitModuleStart(const ModulePtr&); + virtual void visitModuleEnd(const ModulePtr&); + virtual bool visitClassDefStart(const ClassDefPtr&); + virtual void visitClassDefEnd(const ClassDefPtr&); + virtual bool visitExceptionStart(const ExceptionPtr&); + virtual bool visitStructStart(const StructPtr&); + virtual void visitOperation(const OperationPtr&); + void emitUpcall(const ClassDefPtr&, const std::string&); + }; + + class Cpp11ValueVisitor : private ::IceUtil::noncopyable, public Cpp11ObjectVisitor + { + public: + + Cpp11ValueVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&, const std::string&, bool); + + virtual bool visitModuleStart(const ModulePtr&); + virtual void visitModuleEnd(const ModulePtr&); + virtual bool visitClassDefStart(const ClassDefPtr&); + virtual void visitClassDefEnd(const ClassDefPtr&); + virtual bool visitExceptionStart(const ExceptionPtr&); + virtual bool visitStructStart(const StructPtr&); + virtual void visitOperation(const OperationPtr&); + void emitUpcall(const ClassDefPtr&, const std::string&); + }; + + class Cpp11AsyncVisitor : private ::IceUtil::noncopyable, public ParserVisitor + { + public: + + Cpp11AsyncVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&, const std::string&); + + virtual bool visitModuleStart(const ModulePtr&); + virtual void visitModuleEnd(const ModulePtr&); + virtual bool visitClassDefStart(const ClassDefPtr&); + virtual void visitClassDefEnd(const ClassDefPtr&); + virtual void visitOperation(const OperationPtr&); + + private: + + ::IceUtilInternal::Output& H; + + std::string _dllExport; + int _useWstring; + std::list<int> _useWstringHist; + }; + + class Cpp11AsyncImplVisitor : private ::IceUtil::noncopyable, public ParserVisitor + { + public: + + Cpp11AsyncImplVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&, const std::string&); + + virtual bool visitUnitStart(const UnitPtr&); + virtual void visitUnitEnd(const UnitPtr&); + virtual bool visitModuleStart(const ModulePtr&); + virtual void visitModuleEnd(const ModulePtr&); + virtual bool visitClassDefStart(const ClassDefPtr&); + virtual void visitClassDefEnd(const ClassDefPtr&); + virtual void visitOperation(const OperationPtr&); + + private: + + ::IceUtilInternal::Output& H; + ::IceUtilInternal::Output& C; + + std::string _dllExport; + int _useWstring; + std::list<int> _useWstringHist; + }; + + class Cpp11StreamVisitor : private ::IceUtil::noncopyable, public ParserVisitor + { + public: + + Cpp11StreamVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&, const std::string&); + + virtual bool visitModuleStart(const ModulePtr&); + virtual void visitModuleEnd(const ModulePtr&); + virtual bool visitStructStart(const StructPtr&); + virtual bool visitExceptionStart(const ExceptionPtr&); + virtual void visitEnum(const EnumPtr&); + + private: + + ::IceUtilInternal::Output& H; + ::IceUtilInternal::Output& C; + std::string _dllExport; + }; + + class Cpp11InterfaceTraitsVisitor : private ::IceUtil::noncopyable, public ParserVisitor + { + public: + + Cpp11InterfaceTraitsVisitor(::IceUtilInternal::Output&, ::IceUtilInternal::Output&, const std::string&); + + virtual bool visitUnitStart(const UnitPtr&); + virtual void visitUnitEnd(const UnitPtr&); + virtual bool visitClassDefStart(const ClassDefPtr&); + + private: + + ::IceUtilInternal::Output& H; + ::IceUtilInternal::Output& C; + std::string _dllExport; + }; private: |