diff options
Diffstat (limited to 'cpp/src/Slice/CPlusPlusUtil.cpp')
-rw-r--r-- | cpp/src/Slice/CPlusPlusUtil.cpp | 976 |
1 files changed, 822 insertions, 154 deletions
diff --git a/cpp/src/Slice/CPlusPlusUtil.cpp b/cpp/src/Slice/CPlusPlusUtil.cpp index a7206d3219a..9cf3dbb42d5 100644 --- a/cpp/src/Slice/CPlusPlusUtil.cpp +++ b/cpp/src/Slice/CPlusPlusUtil.cpp @@ -24,6 +24,12 @@ using namespace IceUtilInternal; namespace { +string +condString(bool ok, const string& str) +{ + return ok ? str : ""; +} + string toTemplateArg(const string& arg) { if(arg.empty()) @@ -43,19 +49,32 @@ string toTemplateArg(const string& arg) } string +toOptional(const string& s, int typeCtx) +{ + bool cpp11 = (typeCtx & TypeContextCpp11) != 0; + string result = cpp11 ? "Ice::optional" : "IceUtil::Optional"; + result += '<'; + if(cpp11) + { + result += s; + } + else + { + result += toTemplateArg(s); + } + + result += '>'; + return result; +} + + +string stringTypeToString(const TypePtr& type, const StringList& metaData, int typeCtx) { string strType = findMetaData(metaData, typeCtx); if(strType == "wstring" || (typeCtx & TypeContextUseWstring && strType == "")) { - if(featureProfile == IceE) - { - return "::Ice::Wstring"; - } - else - { - return "::std::wstring"; - } + return "::std::wstring"; } else if(strType != "" && strType != "string") { @@ -99,7 +118,7 @@ sequenceTypeToString(const SequencePtr& seq, const StringList& metaData, int typ return "::std::vector<" + s + '>'; } } - string s = typeToString(seq->type(), seq->typeMetaData(), inWstringModule(seq) ? TypeContextUseWstring : 0); + string s = typeToString(seq->type(), seq->typeMetaData(), typeCtx | (inWstringModule(seq) ? TypeContextUseWstring : 0)); return "::std::pair<const " + s + "*, const " + s + "*>"; } else if(seqType.find("%range") == 0) @@ -148,7 +167,6 @@ dictionaryTypeToString(const DictionaryPtr& dict, const StringList& metaData, in } } - void writeParamAllocateCode(Output& out, const TypePtr& type, bool optional, const string& fixedName, const StringList& metaData, int typeCtx, bool endArg) @@ -156,11 +174,11 @@ writeParamAllocateCode(Output& out, const TypePtr& type, bool optional, const st string s = typeToString(type, metaData, typeCtx); if(optional) { - s = "IceUtil::Optional<" + toTemplateArg(s) + '>'; + s = toOptional(s, typeCtx); } out << nl << s << ' ' << fixedName << ';'; - if(!(typeCtx & TypeContextInParam) || !endArg) + if((typeCtx & TypeContextCpp11) || !(typeCtx & TypeContextInParam) || !endArg) { return; // We're done. } @@ -190,23 +208,28 @@ writeParamAllocateCode(Output& out, const TypePtr& type, bool optional, const st { md.push_back("cpp:type:" + seqType.substr(strlen("%range:"))); } - s = typeToString(seq, md); + s = typeToString(seq, md, 0); } if(!s.empty()) { if(optional) { - s = "IceUtil::Optional<" + toTemplateArg(s) + '>'; + s = toOptional(s, typeCtx); } - out << nl << s << " ___" << fixedName << ";"; + out << nl << s << ' ' << fixedName << "_tmp_;"; } } } void -writeParamEndCode(Output& out, const TypePtr& type, bool optional, const string& fixedName, const StringList& metaData) +writeParamEndCode(Output& out, const TypePtr& type, bool optional, const string& fixedName, const StringList& metaData, + const string& obj = "") { + string objPrefix = obj.empty() ? obj : obj + "."; + string paramName = objPrefix + fixedName; + string escapedParamName = objPrefix + fixedName + "_tmp_"; + SequencePtr seq = SequencePtr::dynamicCast(type); if(seq) { @@ -227,14 +250,14 @@ writeParamEndCode(Output& out, const TypePtr& type, bool optional, const string& { if(optional) { - out << nl << "if(___" << fixedName << ")"; + out << nl << "if(" << escapedParamName << ")"; out << sb; - out << nl << fixedName << " = ___" << fixedName << "->second;"; - out << eb; + out << nl << paramName << " = " << escapedParamName << "->second;"; + out << eb; } else { - out << nl << fixedName << " = ___" << fixedName << ".second;"; + out << nl << paramName << " = " << escapedParamName << ".second;"; } } else if(!builtin || @@ -244,32 +267,30 @@ writeParamEndCode(Output& out, const TypePtr& type, bool optional, const string& { if(optional) { - out << nl << "if(___" << fixedName << ")"; + out << nl << "if(" << escapedParamName << ")"; out << sb; - out << nl << fixedName << ".__setIsSet();"; - out << nl << "if(!___" << fixedName << "->empty())"; + out << nl << paramName << ".__setIsSet();"; + out << nl << "if(!" << escapedParamName << "->empty())"; out << sb; - out << nl << fixedName << "->first" << " = &(*___" << fixedName << ")[0];"; - out << nl << fixedName << "->second" << " = " << fixedName << "->first + " << "___" - << fixedName << "->size();"; + out << nl << paramName << "->first" << " = &(*" << escapedParamName << ")[0];"; + out << nl << paramName << "->second" << " = " << paramName << "->first + " << escapedParamName << "->size();"; out << eb; out << nl << "else"; out << sb; - out << nl << fixedName << "->first" << " = " << fixedName << "->second" << " = 0;"; + out << nl << paramName << "->first" << " = " << paramName << "->second" << " = 0;"; out << eb; out << eb; } else { - out << nl << "if(!___" << fixedName << ".empty())"; + out << nl << "if(!" << escapedParamName << ".empty())"; out << sb; - out << nl << fixedName << ".first" << " = &___" << fixedName << "[0];"; - out << nl << fixedName << ".second" << " = " << fixedName << ".first + " << "___" - << fixedName << ".size();"; + out << nl << paramName << ".first" << " = &" << escapedParamName << "[0];"; + out << nl << paramName << ".second" << " = " << paramName << ".first + " << escapedParamName << ".size();"; out << eb; out << nl << "else"; out << sb; - out << nl << fixedName << ".first" << " = " << fixedName << ".second" << " = 0;"; + out << nl << paramName << ".first" << " = " << paramName << ".second" << " = 0;"; out << eb; } } @@ -278,30 +299,42 @@ writeParamEndCode(Output& out, const TypePtr& type, bool optional, const string& { if(optional) { - out << nl << "if(___" << fixedName << ")"; + out << nl << "if(" << escapedParamName << ")"; out << sb; - out << nl << fixedName << ".__setIsSet();"; - out << nl << fixedName << "->first = (*___" << fixedName << ").begin();"; - out << nl << fixedName << "->second = (*___" << fixedName << ").end();"; + out << nl << paramName << ".__setIsSet();"; + out << nl << paramName << "->first = (*" << escapedParamName << ").begin();"; + out << nl << paramName << "->second = (*" << escapedParamName << ").end();"; out << eb; } else { - out << nl << fixedName << ".first = ___" << fixedName << ".begin();"; - out << nl << fixedName << ".second = ___" << fixedName << ".end();"; + out << nl << paramName << ".first = " << escapedParamName << ".begin();"; + out << nl << paramName << ".second = " << escapedParamName << ".end();"; } } } } void -writeMarshalUnmarshalParams(Output& out, const ParamDeclList& params, const OperationPtr& op, bool marshal, bool prepend, int typeCtx) +writeMarshalUnmarshalParams(Output& out, const ParamDeclList& params, const OperationPtr& op, bool marshal, + bool prepend, int typeCtx, const string& customStream = "", const string& retP = "", const string& obj = "") { string prefix = prepend ? paramPrefix : ""; + string returnValueS = retP.empty() ? string("ret") : retP; + string objPrefix = obj.empty() ? obj : obj + "."; + + string stream = customStream; + if(stream.empty()) + { + stream = marshal ? "ostr" : "istr"; + } + + bool cpp11 = (typeCtx & TypeContextCpp11) != 0; // // Marshal non optional parameters. // + ParamDeclList requiredParams; ParamDeclList optionals; for(ParamDeclList::const_iterator p = params.begin(); p != params.end(); ++p) { @@ -311,57 +344,161 @@ writeMarshalUnmarshalParams(Output& out, const ParamDeclList& params, const Oper } else { - writeMarshalUnmarshalCode(out, (*p)->type(), false, 0, fixKwd(prefix + (*p)->name()), marshal, (*p)->getMetaData(), - typeCtx); + requiredParams.push_back(*p); } } - if(op && op->returnType()) + + + if(!requiredParams.empty() || (op && op->returnType() && !op->returnIsOptional())) { - if(!op->returnIsOptional()) + if(cpp11) + { + out << nl; + if(marshal) + { + out << stream << "->writeAll"; + } + else + { + out << stream << "->readAll"; + } + out << spar; + for(ParamDeclList::const_iterator p = requiredParams.begin(); p != requiredParams.end(); ++p) + { + out << objPrefix + fixKwd(prefix + (*p)->name()); + } + if(op && op->returnType() && !op->returnIsOptional()) + { + out << objPrefix + returnValueS; + } + out << epar << ";"; + } + else { - writeMarshalUnmarshalCode(out, op->returnType(), false, 0, "__ret", marshal, op->getMetaData(), typeCtx); + for(ParamDeclList::const_iterator p = requiredParams.begin(); p != requiredParams.end(); ++p) + { + writeMarshalUnmarshalCode(out, (*p)->type(), false, 0, fixKwd(prefix + (*p)->name()), marshal, (*p)->getMetaData(), + typeCtx, customStream, true, obj); + } + + if(op && op->returnType()) + { + if(!op->returnIsOptional()) + { + writeMarshalUnmarshalCode(out, op->returnType(), false, 0, returnValueS, marshal, op->getMetaData(), typeCtx, + customStream, true, obj); + } + } } } - // - // Sort optional parameters by tag. - // - class SortFn + if(!optionals.empty() || (op && op->returnType() && op->returnIsOptional())) { - public: - static bool compare(const ParamDeclPtr& lhs, const ParamDeclPtr& rhs) + // + // Sort optional parameters by tag. + // + class SortFn { - return lhs->tag() < rhs->tag(); - } - }; - optionals.sort(SortFn::compare); + public: + static bool compare(const ParamDeclPtr& lhs, const ParamDeclPtr& rhs) + { + return lhs->tag() < rhs->tag(); + } + }; + optionals.sort(SortFn::compare); - // - // Marshal optional parameters. - // - bool checkReturnType = op && op->returnIsOptional(); - for(ParamDeclList::const_iterator p = optionals.begin(); p != optionals.end(); ++p) - { - if(checkReturnType && op->returnTag() < (*p)->tag()) + if(cpp11) { - writeMarshalUnmarshalCode(out, op->returnType(), true, op->returnTag(), "__ret", marshal, - op->getMetaData(), typeCtx); - checkReturnType = false; + out << nl; + if(marshal) + { + out << stream << "->writeAll"; + } + else + { + out << stream << "->readAll"; + } + out << spar; + + { + // + // Tags + // + ostringstream os; + os << '{'; + bool checkReturnType = op && op->returnIsOptional(); + bool insertComma = false; + for(ParamDeclList::const_iterator p = optionals.begin(); p != optionals.end(); ++p) + { + if(checkReturnType && op->returnTag() < (*p)->tag()) + { + os << condString(insertComma, ", ") << op->returnTag(); + checkReturnType = false; + insertComma = true; + } + os << condString(insertComma, ", ") << (*p)->tag(); + insertComma = true; + } + if(checkReturnType) + { + os << condString(insertComma, ", ") << op->returnTag(); + } + os << '}'; + out << os.str(); + } + + { + // + // Parameters + // + bool checkReturnType = op && op->returnIsOptional(); + for(ParamDeclList::const_iterator p = optionals.begin(); p != optionals.end(); ++p) + { + if(checkReturnType && op->returnTag() < (*p)->tag()) + { + out << objPrefix + returnValueS; + checkReturnType = false; + } + out << objPrefix + fixKwd(prefix + (*p)->name()); + } + if(checkReturnType) + { + out << objPrefix + returnValueS; + } + } + out << epar << ";"; + } + else + { + + // + // Marshal optional parameters. + // + + bool checkReturnType = op && op->returnIsOptional(); + for(ParamDeclList::const_iterator p = optionals.begin(); p != optionals.end(); ++p) + { + if(checkReturnType && op->returnTag() < (*p)->tag()) + { + writeMarshalUnmarshalCode(out, op->returnType(), true, op->returnTag(), returnValueS, marshal, + op->getMetaData(), typeCtx, customStream, true, obj); + + checkReturnType = false; + } + writeMarshalUnmarshalCode(out, (*p)->type(), true, (*p)->tag(), fixKwd(prefix + (*p)->name()), marshal, + (*p)->getMetaData(), typeCtx, customStream, true, obj); + } + if(checkReturnType) + { + writeMarshalUnmarshalCode(out, op->returnType(), true, op->returnTag(), returnValueS, marshal, op->getMetaData(), + typeCtx, customStream, true, obj); + } } - writeMarshalUnmarshalCode(out, (*p)->type(), true, (*p)->tag(), fixKwd(prefix + (*p)->name()), marshal, - (*p)->getMetaData(), typeCtx); - } - if(checkReturnType) - { - writeMarshalUnmarshalCode(out, op->returnType(), true, op->returnTag(), "__ret", marshal, op->getMetaData(), - typeCtx); } } - } -Slice::FeatureProfile Slice::featureProfile = Slice::Ice; -string Slice::paramPrefix = "__p_"; +string Slice::paramPrefix = "iceP_"; char Slice::ToIfdef::operator()(char c) @@ -439,10 +576,10 @@ Slice::printDllExportStuff(Output& out, const string& dllExport) { out << sp; out << "\n#ifndef " << dllExport; - out << "\n# ifdef " << dllExport << "_EXPORTS"; - out << "\n# define " << dllExport << " ICE_DECLSPEC_EXPORT"; - out << "\n# elif defined(ICE_STATIC_LIBS)"; + out << "\n# if defined(ICE_STATIC_LIBS)"; out << "\n# define " << dllExport << " /**/"; + out << "\n# elif defined(" << dllExport << "_EXPORTS)"; + out << "\n# define " << dllExport << " ICE_DECLSPEC_EXPORT"; out << "\n# else"; out << "\n# define " << dllExport << " ICE_DECLSPEC_IMPORT"; out << "\n# endif"; @@ -450,10 +587,36 @@ Slice::printDllExportStuff(Output& out, const string& dllExport) } } +bool +Slice::isMovable(const TypePtr& type) +{ + BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); + if(builtin) + { + switch(builtin->kind()) + { + case Builtin::KindString: + case Builtin::KindObject: + case Builtin::KindObjectProxy: + case Builtin::KindLocalObject: + case Builtin::KindValue: + { + return true; + } + default: + { + return false; + } + } + } + return !EnumPtr::dynamicCast(type); +} string Slice::typeToString(const TypePtr& type, const StringList& metaData, int typeCtx) { + bool cpp11 = (typeCtx & TypeContextCpp11) != 0; + static const char* builtinTable[] = { "::Ice::Byte", @@ -466,7 +629,24 @@ Slice::typeToString(const TypePtr& type, const StringList& metaData, int typeCtx "::std::string", "::Ice::ObjectPtr", "::Ice::ObjectPrx", - "::Ice::LocalObjectPtr" + "::Ice::LocalObjectPtr", + "::Ice::ValuePtr" + }; + + static const char* cpp11BuiltinTable[] = + { + "::Ice::Byte", + "bool", + "short", + "int", + "long long int", + "float", + "double", + "::std::string", + "::std::shared_ptr<::Ice::Object>", + "::std::shared_ptr<::Ice::ObjectPrx>", + "::std::shared_ptr<void>", + "::std::shared_ptr<::Ice::Value>" }; BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); @@ -478,20 +658,55 @@ Slice::typeToString(const TypePtr& type, const StringList& metaData, int typeCtx } else { - return builtinTable[builtin->kind()]; + if(cpp11) + { + if(builtin->kind() == Builtin::KindObject && !(typeCtx & TypeContextLocal)) + { + return "::std::shared_ptr<::Ice::Value>"; + } + else + { + return cpp11BuiltinTable[builtin->kind()]; + } + } + else + { + return builtinTable[builtin->kind()]; + } } } ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type); if(cl) { - return fixKwd(cl->scoped() + "Ptr"); + if(cpp11) + { + if(cl->definition() && cl->definition()->isDelegate()) + { + return classDefToDelegateString(cl->definition()); + } + else if(cl->isInterface() && !cl->isLocal()) + { + return "std::shared_ptr<::Ice::Value>"; + } + else + { + return "::std::shared_ptr<" + cl->scoped() + ">"; + } + } + else + { + return cl->scoped() + "Ptr"; + } } StructPtr st = StructPtr::dynamicCast(type); if(st) { - if(findMetaData(st->getMetaData()) == "%class") + // + // C++11 mapping doesn't accept cpp:class metadata + // + if(!cpp11 && findMetaData(st->getMetaData()) == "%class") { return fixKwd(st->scoped() + "Ptr"); } @@ -501,7 +716,26 @@ Slice::typeToString(const TypePtr& type, const StringList& metaData, int typeCtx ProxyPtr proxy = ProxyPtr::dynamicCast(type); if(proxy) { - return fixKwd(proxy->_class()->scoped() + "Prx"); + if(cpp11) + { + ClassDefPtr def = proxy->_class()->definition(); + // + // Non local classes without operations map to the base + // proxy class shared_ptr<Ice::ObjectPrx> + // + if(def && !def->isInterface() && def->allOperations().empty()) + { + return "::std::shared_ptr<::Ice::ObjectPrx>"; + } + else + { + return "::std::shared_ptr<" + fixKwd(proxy->_class()->scoped() + "Prx") + ">"; + } + } + else + { + return fixKwd(proxy->_class()->scoped() + "Prx"); + } } SequencePtr seq = SequencePtr::dynamicCast(type); @@ -536,7 +770,7 @@ Slice::typeToString(const TypePtr& type, bool optional, const StringList& metaDa { if(optional) { - return "IceUtil::Optional<" + toTemplateArg(typeToString(type, metaData, typeCtx)) + ">"; + return toOptional(typeToString(type, metaData, typeCtx), typeCtx); } else { @@ -554,7 +788,7 @@ Slice::returnTypeToString(const TypePtr& type, bool optional, const StringList& if(optional) { - return "IceUtil::Optional<" + toTemplateArg(typeToString(type, metaData, typeCtx)) + ">"; + return toOptional(typeToString(type, metaData, typeCtx), typeCtx); } return typeToString(type, metaData, typeCtx); @@ -563,7 +797,9 @@ Slice::returnTypeToString(const TypePtr& type, bool optional, const StringList& string Slice::inputTypeToString(const TypePtr& type, bool optional, const StringList& metaData, int typeCtx) { - static const char* inputBuiltinTable[] = + bool cpp11 = (typeCtx & TypeContextCpp11) != 0; + + static const char* cpp98InputBuiltinTable[] = { "::Ice::Byte", "bool", @@ -575,14 +811,31 @@ Slice::inputTypeToString(const TypePtr& type, bool optional, const StringList& m "const ::std::string&", "const ::Ice::ObjectPtr&", "const ::Ice::ObjectPrx&", - "const ::Ice::LocalObjectPtr&" + "const ::Ice::LocalObjectPtr&", + "const ::Ice::ValuePtr&" + }; + + static const char* cpp11InputBuiltinTable[] = + { + "::Ice::Byte", + "bool", + "short", + "int", + "long long int", + "float", + "double", + "const ::std::string&", + "const ::std::shared_ptr<::Ice::Object>&", + "const ::std::shared_ptr<::Ice::ObjectPrx>&", + "const ::std::shared_ptr<void>&", + "const ::std::shared_ptr<::Ice::Value>&" }; typeCtx |= TypeContextInParam; if(optional) { - return "const IceUtil::Optional<" + toTemplateArg(typeToString(type, metaData, typeCtx)) +">&"; + return "const " + toOptional(typeToString(type, metaData, typeCtx), typeCtx) + '&'; } BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); @@ -590,34 +843,91 @@ Slice::inputTypeToString(const TypePtr& type, bool optional, const StringList& m { if(builtin->kind() == Builtin::KindString) { - return string("const ") + stringTypeToString(type, metaData, typeCtx) + "&"; + return string("const ") + stringTypeToString(type, metaData, typeCtx) + '&'; } else { - return inputBuiltinTable[builtin->kind()]; + if(cpp11) + { + if(builtin->kind() == Builtin::KindObject && !(typeCtx & TypeContextLocal)) + { + return "const ::std::shared_ptr<::Ice::Value>&"; + } + else + { + return cpp11InputBuiltinTable[builtin->kind()]; + } + } + else + { + return cpp98InputBuiltinTable[builtin->kind()]; + } } } ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type); if(cl) { - return "const " + fixKwd(cl->scoped() + "Ptr&"); + if(cpp11) + { + if(cl->definition() && cl->definition()->isDelegate()) + { + return classDefToDelegateString(cl->definition(), typeCtx); + } + else if(cl->isInterface() && !cl->isLocal()) + { + return "const ::std::shared_ptr<::Ice::Value>&"; + } + else + { + return "const ::std::shared_ptr<" + fixKwd(cl->scoped()) + ">&"; + } + } + else + { + return "const " + fixKwd(cl->scoped() + "Ptr&"); + } } StructPtr st = StructPtr::dynamicCast(type); if(st) { - if(findMetaData(st->getMetaData()) == "%class") + if(cpp11) { - return "const " + fixKwd(st->scoped() + "Ptr&"); + return "const " + fixKwd(st->scoped()) + "&"; + } + else + { + if(findMetaData(st->getMetaData()) == "%class") + { + return "const " + fixKwd(st->scoped() + "Ptr&"); + } + else + { + return "const " + fixKwd(st->scoped()) + "&"; + } } - return "const " + fixKwd(st->scoped()) + "&"; } ProxyPtr proxy = ProxyPtr::dynamicCast(type); if(proxy) { - return "const " + fixKwd(proxy->_class()->scoped() + "Prx&"); + if(cpp11) + { + ClassDefPtr def = proxy->_class()->definition(); + if(def && !def->isInterface() && def->allOperations().empty()) + { + return "const ::std::shared_ptr<::Ice::ObjectPrx>&"; + } + else + { + return "const ::std::shared_ptr<" + fixKwd(proxy->_class()->scoped() + "Prx") + ">&"; + } + } + else + { + return "const " + fixKwd(proxy->_class()->scoped() + "Prx&"); + } } EnumPtr en = EnumPtr::dynamicCast(type); @@ -650,6 +960,8 @@ Slice::inputTypeToString(const TypePtr& type, bool optional, const StringList& m string Slice::outputTypeToString(const TypePtr& type, bool optional, const StringList& metaData, int typeCtx) { + bool cpp11 = (typeCtx & TypeContextCpp11) != 0; + static const char* outputBuiltinTable[] = { "::Ice::Byte&", @@ -661,13 +973,30 @@ Slice::outputTypeToString(const TypePtr& type, bool optional, const StringList& "::Ice::Double&", "::std::string&", "::Ice::ObjectPtr&", - "::Ice::ObjectPrx&", - "::Ice::LocalObjectPtr&" + "::Ice::ObjectPrxPtr&", + "::Ice::LocalObjectPtr&", + "::Ice::ValuePtr&" + }; + + static const char* cpp11OutputBuiltinTable[] = + { + "::Ice::Byte&", + "bool&", + "short&", + "int&", + "long long int&", + "float&", + "double&", + "::std::string&", + "::std::shared_ptr<::Ice::Object>&", + "::std::shared_ptr<::Ice::ObjectPrx>&", + "::std::shared_ptr<void>&", + "::std::shared_ptr<::Ice::Value>&" }; if(optional) { - return "IceUtil::Optional<" + toTemplateArg(typeToString(type, metaData, typeCtx)) +">&"; + return toOptional(typeToString(type, metaData, typeCtx), typeCtx) + '&'; } BuiltinPtr builtin = BuiltinPtr::dynamicCast(type); @@ -679,30 +1008,84 @@ Slice::outputTypeToString(const TypePtr& type, bool optional, const StringList& } else { - return outputBuiltinTable[builtin->kind()]; + if(cpp11) + { + if(builtin->kind() == Builtin::KindObject && !(typeCtx & TypeContextLocal)) + { + return "::std::shared_ptr<::Ice::Value>"; + } + else + { + return cpp11OutputBuiltinTable[builtin->kind()]; + } + } + else + { + return outputBuiltinTable[builtin->kind()]; + } } } ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type); if(cl) { - return fixKwd(cl->scoped() + "Ptr&"); + if(cpp11) + { + if(cl->definition() && cl->definition()->isDelegate()) + { + return classDefToDelegateString(cl->definition(), typeCtx) + "&"; + } + else if(cl->isInterface() && !cl->isLocal()) + { + return "::std::shared_ptr<::Ice::Value>&"; + } + else + { + return "::std::shared_ptr<" + fixKwd(cl->scoped()) + ">&"; + } + } + else + { + return fixKwd(cl->scoped() + "Ptr&"); + } } StructPtr st = StructPtr::dynamicCast(type); if(st) { - if(findMetaData(st->getMetaData()) == "%class") + if(!cpp11 && findMetaData(st->getMetaData()) == "%class") { return fixKwd(st->scoped() + "Ptr&"); } - return fixKwd(st->scoped()) + "&"; + else + { + return fixKwd(st->scoped()) + "&"; + } } ProxyPtr proxy = ProxyPtr::dynamicCast(type); if(proxy) { - return fixKwd(proxy->_class()->scoped() + "Prx&"); + if(cpp11) + { + ClassDefPtr def = proxy->_class()->definition(); + // + // Non local classes without operations map to the base + // proxy class shared_ptr<Ice::ObjectPrx> + // + if(def && !def->isInterface() && def->allOperations().empty()) + { + return "::std::shared_ptr<::Ice::ObjectPrx>"; + } + else + { + return "::std::shared_ptr<" + fixKwd(proxy->_class()->scoped() + "Prx") + ">&"; + } + } + else + { + return fixKwd(proxy->_class()->scoped() + "Prx&"); + } } SequencePtr seq = SequencePtr::dynamicCast(type); @@ -727,23 +1110,23 @@ Slice::outputTypeToString(const TypePtr& type, bool optional, const StringList& } string -Slice::operationModeToString(Operation::Mode mode) +Slice::operationModeToString(Operation::Mode mode, bool cpp11) { switch(mode) { case Operation::Normal: { - return "::Ice::Normal"; + return cpp11 ? "::Ice::OperationMode::Normal" : "::Ice::Normal"; } case Operation::Nonmutating: { - return "::Ice::Nonmutating"; + return cpp11 ? "::Ice::OperationMode::Nonmutating" : "::Ice::Nonmutating"; } case Operation::Idempotent: { - return "::Ice::Idempotent"; + return cpp11 ? "::Ice::OperationMode::Idempotent" : "::Ice::Idempotent"; } default: @@ -775,7 +1158,7 @@ Slice::opFormatTypeToString(const OperationPtr& op) } // -// If the passed name is a keyword, return the name with a "_cxx_" prefix; +// If the passed name is a keyword, return the name with a "_cpp_" prefix; // otherwise, return the name unchanged. // @@ -792,14 +1175,15 @@ lookupKwd(const string& name) // static const string keywordList[] = { - "and", "and_eq", "asm", "auto", "bit_and", "bit_or", "bool", "break", "case", "catch", "char", - "class", "compl", "const", "const_cast", "continue", "default", "delete", "do", "double", - "dynamic_cast", "else", "enum", "explicit", "export", "extern", "false", "float", "for", - "friend", "goto", "if", "inline", "int", "long", "mutable", "namespace", "new", "not", "not_eq", - "operator", "or", "or_eq", "private", "protected", "public", "register", "reinterpret_cast", - "return", "short", "signed", "sizeof", "static", "static_cast", "struct", "switch", "template", - "this", "throw", "true", "try", "typedef", "typeid", "typename", "union", "unsigned", "using", - "virtual", "void", "volatile", "wchar_t", "while", "xor", "xor_eq" + "alignas", "alignof", "and", "and_eq", "asm", "auto", "bit_and", "bit_or", "bool", "break", + "case", "catch", "char", "char16_t", "char32_t", "class", "compl", "const", "const_exptr", "const_cast", "continue", + "decltype", "default", "delete", "do", "double", "dynamic_cast", + "else", "enum", "explicit", "export", "extern", "false", "float", "for", "friend", + "goto", "if", "inline", "int", "long", "mutable", "namespace", "new", "noexcept", "not", "not_eq", + "operator", "or", "or_eq", "private", "protected", "public", "register", "reinterpret_cast", "return", + "short", "signed", "sizeof", "static", "static_assert", "static_cast", "struct", "switch", + "template", "this", "thread_local", "throw", "true", "try", "typedef", "typeid", "typename", + "union", "unsigned", "using", "virtual", "void", "volatile", "wchar_t", "while", "xor", "xor_eq" }; bool found = binary_search(&keywordList[0], &keywordList[sizeof(keywordList) / sizeof(*keywordList)], @@ -845,8 +1229,8 @@ splitScopedName(const string& scoped) // // If the passed name is a scoped name, return the identical scoped name, // but with all components that are C++ keywords replaced by -// their "_cxx_"-prefixed version; otherwise, if the passed name is -// not scoped, but a C++ keyword, return the "_cxx_"-prefixed name; +// their "_cpp_"-prefixed version; otherwise, if the passed name is +// not scoped, but a C++ keyword, return the "_cpp_"-prefixed name; // otherwise, return the name unchanged. // string @@ -868,16 +1252,19 @@ Slice::fixKwd(const string& name) void Slice::writeMarshalUnmarshalCode(Output& out, const TypePtr& type, bool optional, int tag, const string& param, - bool marshal, const StringList& metaData, int typeCtx, const string& str, bool pointer) + bool marshal, const StringList& metaData, int typeCtx, const string& customStream, bool pointer, + const string& obj) { + string objPrefix = obj.empty() ? obj : obj + "."; + ostringstream os; - if(str.empty()) + if(customStream.empty()) { - os << (marshal ? "__os" : "__is"); + os << (marshal ? "ostr" : "istr"); } else { - os << str; + os << customStream; } string deref; @@ -916,52 +1303,63 @@ Slice::writeMarshalUnmarshalCode(Output& out, const TypePtr& type, bool optional BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type()); if(builtin && builtin->kind() == Builtin::KindByte) { - out << nl << func << param << ");"; + out << nl << func << objPrefix << param << ");"; return; } - out << nl << func << "___" << param << ");"; - writeParamEndCode(out, seq, optional, param, metaData); + out << nl << func << objPrefix << param << "_tmp_);"; + writeParamEndCode(out, seq, optional, param, metaData, obj); return; } else if(seqType.find("%range") == 0) { - out << nl << func << "___" << param << ");"; - writeParamEndCode(out, seq, optional, param, metaData); + out << nl << func << objPrefix << param << "_tmp_);"; + writeParamEndCode(out, seq, optional, param, metaData, obj); return; } } } - out << nl << func << param << ");"; + out << nl << func << objPrefix << param << ");"; } void -Slice::writeMarshalCode(Output& out, const ParamDeclList& params, const OperationPtr& op, bool prepend, int typeCtx) +Slice::writeMarshalCode(Output& out, const ParamDeclList& params, const OperationPtr& op, bool prepend, int typeCtx, + const string& customStream, const string& retP) { - writeMarshalUnmarshalParams(out, params, op, true, prepend, typeCtx); + writeMarshalUnmarshalParams(out, params, op, true, prepend, typeCtx, customStream, retP); } void -Slice::writeUnmarshalCode(Output& out, const ParamDeclList& params, const OperationPtr& op, bool prepend, int typeCtx) +Slice::writeUnmarshalCode(Output& out, const ParamDeclList& params, const OperationPtr& op, bool prepend, int typeCtx, + const string& customStream, const string& retP, const string& obj) { - writeMarshalUnmarshalParams(out, params, op, false, prepend, typeCtx); + writeMarshalUnmarshalParams(out, params, op, false, prepend, typeCtx, customStream, retP, obj); } void -Slice::writeAllocateCode(Output& out, const ParamDeclList& params, const OperationPtr& op, bool prepend, int typeCtx) +Slice::writeAllocateCode(Output& out, const ParamDeclList& params, const OperationPtr& op, bool prepend, int typeCtx, + const string& customRet) { string prefix = prepend ? paramPrefix : ""; + string returnValueS = customRet; + if(returnValueS.empty()) + { + returnValueS = "ret"; + } + for(ParamDeclList::const_iterator p = params.begin(); p != params.end(); ++p) { writeParamAllocateCode(out, (*p)->type(), (*p)->optional(), fixKwd(prefix + (*p)->name()), (*p)->getMetaData(), - typeCtx, getEndArg((*p)->type(),(*p)->getMetaData(), (*p)->name()) != (*p)->name()); + typeCtx, getEndArg((*p)->type(), (*p)->getMetaData(), (*p)->name()) != (*p)->name()); } + if(op && op->returnType()) { - writeParamAllocateCode(out, op->returnType(), op->returnIsOptional(), "__ret", op->getMetaData(), typeCtx, - getEndArg(op->returnType(), op->getMetaData(), "__ret") != "__ret"); + writeParamAllocateCode(out, op->returnType(), op->returnIsOptional(), returnValueS, op->getMetaData(), typeCtx, + getEndArg(op->returnType(), op->getMetaData(), returnValueS) != returnValueS); } + } string @@ -986,11 +1384,11 @@ Slice::getEndArg(const TypePtr& type, const StringList& metaData, const string& builtin->kind() != Builtin::KindObject && builtin->kind() != Builtin::KindObjectProxy) { - endArg = "___" + endArg; + endArg += "_tmp_"; } else if(!builtin || builtin->kind() != Builtin::KindByte) { - endArg = "___" + endArg; + endArg += "_tmp_"; } } else if(seqType.find("%range") == 0) @@ -1000,7 +1398,7 @@ Slice::getEndArg(const TypePtr& type, const StringList& metaData, const string& { md.push_back("cpp:type:" + seqType.substr(strlen("%range:"))); } - endArg = "___" + endArg; + endArg += "_tmp_"; } } return endArg; @@ -1016,8 +1414,247 @@ Slice::writeEndCode(Output& out, const ParamDeclList& params, const OperationPtr } if(op && op->returnType()) { - writeParamEndCode(out, op->returnType(), op->returnIsOptional(), "__ret", op->getMetaData()); + writeParamEndCode(out, op->returnType(), op->returnIsOptional(), "ret", op->getMetaData()); + } +} + +void +Slice::writeMarshalUnmarshalDataMemberInHolder(IceUtilInternal::Output& C, + const string& holder, + const DataMemberPtr& p, + bool marshal) +{ + writeMarshalUnmarshalCode(C, p->type(), p->optional(), p->tag(), holder + fixKwd(p->name()), marshal, + p->getMetaData()); +} + +void +Slice::writeMarshalUnmarshalAllInHolder(IceUtilInternal::Output& out, + const string& holder, + const DataMemberList& dataMembers, + bool optional, + bool marshal) +{ + if(dataMembers.empty()) + { + return; + } + + string stream = marshal ? "ostr" : "istr"; + string streamOp = marshal ? "writeAll" : "readAll"; + + out << nl << stream << "->" << streamOp; + out << spar; + + if(optional) + { + ostringstream os; + os << "{"; + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + if(q != dataMembers.begin()) + { + os << ", "; + } + os << (*q)->tag(); + } + os << "}"; + out << os.str(); + } + + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + out << holder + fixKwd((*q)->name()); } + + out << epar << ";"; + +} + +void +Slice::writeStreamHelpers(Output& out, + const ContainedPtr& c, + DataMemberList dataMembers, + bool hasBaseDataMembers, + bool checkClassMetaData, + bool cpp11) +{ + // If c is a C++11 class/exception whose base class contains data members (recursively), then we need to generate + // an StreamWriter even if its implementation is empty. This is becuase our default marsaling uses ice_tuple() which + // contains all of our class/exception's data members as well the base data members, which breaks marshaling. This + // is not an issue for structs. + if(dataMembers.empty() && !(cpp11 && hasBaseDataMembers)) + { + return; + } + + DataMemberList requiredMembers; + DataMemberList optionalMembers; + + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + if((*q)->optional()) + { + optionalMembers.push_back(*q); + } + else + { + requiredMembers.push_back(*q); + } + } + + // Sort optional data members + class SortFn + { + public: + static bool compare(const DataMemberPtr& lhs, const DataMemberPtr& rhs) + { + return lhs->tag() < rhs->tag(); + } + }; + optionalMembers.sort(SortFn::compare); + + string scoped = c->scoped(); + bool classMetaData = checkClassMetaData ? (findMetaData(c->getMetaData(), false) == "%class") : false; + string fullName = classMetaData ? fixKwd(scoped + "Ptr") : fixKwd(scoped); + string holder = classMetaData ? "v->" : "v."; + + // + // Generate StreamWriter + // + // Only generate StreamWriter specializations if we are generating for C++98 or + // we are generating for C++11 with optional data members and no base class data members + // + if(!cpp11 || !optionalMembers.empty() || hasBaseDataMembers) + { + out << nl << "template<typename S>"; + out << nl << "struct StreamWriter" << (cpp11 ? "<" : "< ") << fullName << ", S>"; + out << sb; + if(requiredMembers.empty() && optionalMembers.empty()) + { + out << nl << "static void write(S*, const " << fullName << "&)"; + } + else + { + out << nl << "static void write(S* ostr, const " << fullName << "& v)"; + } + + out << sb; + + if(cpp11) + { + writeMarshalUnmarshalAllInHolder(out, holder, requiredMembers, false, true); + writeMarshalUnmarshalAllInHolder(out, holder, optionalMembers, true, true); + } + else + { + for(DataMemberList::const_iterator q = requiredMembers.begin(); q != requiredMembers.end(); ++q) + { + writeMarshalUnmarshalDataMemberInHolder(out, holder, *q, true); + } + + for(DataMemberList::const_iterator q = optionalMembers.begin(); q != optionalMembers.end(); ++q) + { + writeMarshalUnmarshalDataMemberInHolder(out, holder, *q, true); + } + } + + out << eb; + out << eb << ";" << nl; + } + + // + // Generate StreamWriter + // + out << nl << "template<typename S>"; + out << nl << "struct StreamReader" << (cpp11 ? "<" : "< ") << fullName << ", S>"; + out << sb; + if (requiredMembers.empty() && optionalMembers.empty()) + { + out << nl << "static void read(S*, " << fullName << "&)"; + } + else + { + out << nl << "static void read(S* istr, " << fullName << "& v)"; + } + + out << sb; + + if(cpp11) + { + writeMarshalUnmarshalAllInHolder(out, holder, requiredMembers, false, false); + writeMarshalUnmarshalAllInHolder(out, holder, optionalMembers, true, false); + } + else + { + for(DataMemberList::const_iterator q = requiredMembers.begin(); q != requiredMembers.end(); ++q) + { + writeMarshalUnmarshalDataMemberInHolder(out, holder, *q, false); + } + + for(DataMemberList::const_iterator q = optionalMembers.begin(); q != optionalMembers.end(); ++q) + { + writeMarshalUnmarshalDataMemberInHolder(out, holder, *q, false); + } + } + + out << eb; + out << eb << ";" << nl; +} + +void +Slice::writeIceTuple(::IceUtilInternal::Output& out, DataMemberList dataMembers, int typeCtx) +{ + out << sp << nl << "std::tuple<"; + for(DataMemberList::const_iterator q = dataMembers.begin(); q != dataMembers.end(); ++q) + { + if(q != dataMembers.begin()) + { + out << ", "; + } + out << "const "; + out << typeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), typeCtx | TypeContextCpp11) << "&"; + } + out << "> ice_tuple() const"; + + out << sb; + out << nl << "return std::tie("; + for(DataMemberList::const_iterator pi = dataMembers.begin(); pi != dataMembers.end(); ++pi) + { + if(pi != dataMembers.begin()) + { + out << ", "; + } + out << fixKwd((*pi)->name()); + } + out << ");" << eb; +} + +bool +Slice::findMetaData(const string& prefix, const ClassDeclPtr& cl, string& value) +{ + if(findMetaData(prefix, cl->getMetaData(), value)) + { + return true; + } + + ClassDefPtr def = cl->definition(); + return def ? findMetaData(prefix, def->getMetaData(), value) : false; +} + +bool +Slice::findMetaData(const string& prefix, const StringList& metaData, string& value) +{ + for(StringList::const_iterator i = metaData.begin(); i != metaData.end(); i++) + { + string s = *i; + if(s.find(prefix) == 0) + { + value = s.substr(prefix.size()); + return true; + } + } + return false; } string @@ -1041,28 +1678,23 @@ Slice::findMetaData(const StringList& metaData, int typeCtx) // the return value is % followed by the string after cpp:. // // The priority of the metadata is as follows: - // 1: protobuf - // 2: array, range, view-type for "view" parameters - // 3: class + // 1: array, range (C++98 only), view-type for "view" parameters + // 2: class (C++98 only), unscoped (C++11 only) + // if(pos != string::npos) { string ss = str.substr(prefix.size()); - if(ss.find("protobuf:") == 0) - { - return str.substr(pos + 1); - } - if(typeCtx & (TypeContextInParam | TypeContextAMIPrivateEnd)) { - if(ss.find("range:") == 0) + if(ss.find("view-type:") == 0) { - return string("%") + str.substr(prefix.size()); + return str.substr(pos + 1); } - else if(ss.find("view-type:") == 0) + else if(ss.find("range:") == 0 && !(typeCtx & TypeContextCpp11)) { - return str.substr(pos + 1); + return string("%") + str.substr(prefix.size()); } } @@ -1078,21 +1710,25 @@ Slice::findMetaData(const StringList& metaData, int typeCtx) { return "%array"; } - else if(ss == "range") + else if(ss == "range" && !(typeCtx & TypeContextCpp11)) { return "%range"; } } // - // Otherwise if the data is "class" it is returned. + // Otherwise if the data is "class", "unscoped" it is returned. // else { string ss = str.substr(prefix.size()); - if(ss == "class") + if(ss == "class" && !(typeCtx & TypeContextCpp11)) { return "%class"; } + else if(ss == "unscoped" && (typeCtx & TypeContextCpp11)) + { + return "%unscoped"; + } } } } @@ -1144,3 +1780,35 @@ Slice::getDataMemberRef(const DataMemberPtr& p) return "(*" + name + ")"; } } + +string +Slice::classDefToDelegateString(const ClassDefPtr& cl, int typeCtx) +{ + assert(cl->isDelegate()); + + // A delegate only has one operation + OperationPtr op = cl->allOperations().front(); + + TypePtr ret = op->returnType(); + string retS = returnTypeToString(ret, op->returnIsOptional(), op->getMetaData(), typeCtx); + + string t = "::std::function<" + retS + "("; + + ParamDeclList paramList = cl->allOperations().front()->parameters(); + for(ParamDeclList::iterator q = paramList.begin(); q != paramList.end(); ++q) + { + if((*q)->isOutParam()) + { + t += outputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), typeCtx); + } + else + { + t += inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), typeCtx); + } + + t += distance(q, paramList.end()) == 1 ? "" : ", "; + } + + t += ")>"; + return t; +} |