diff options
author | Bernard Normier <bernard@zeroc.com> | 2012-09-21 11:39:40 -0400 |
---|---|---|
committer | Bernard Normier <bernard@zeroc.com> | 2012-09-21 11:39:40 -0400 |
commit | d2b0b523f878a2db545e03610836ff342888a67c (patch) | |
tree | 1519565b15c643ba657d39e86389ec88de91e008 /cpp | |
parent | Reverted temp debug addition to StreamI.cpp (diff) | |
download | ice-d2b0b523f878a2db545e03610836ff342888a67c.tar.bz2 ice-d2b0b523f878a2db545e03610836ff342888a67c.tar.xz ice-d2b0b523f878a2db545e03610836ff342888a67c.zip |
Partial fix for ICE-3393:
- cpp:protobuf is now an alias for cpp:type
- StreamTraitType is now extensible
- StreamTrait<> has now a third template parameter, typename Enabler = void, for std::enable_if expressions
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/include/Ice/StreamTraits.h | 50 | ||||
-rw-r--r-- | cpp/include/Slice/CPlusPlusUtil.h | 1 | ||||
-rw-r--r-- | cpp/src/Slice/CPlusPlusUtil.cpp | 252 | ||||
-rw-r--r-- | cpp/src/slice2cpp/Gen.cpp | 104 |
4 files changed, 114 insertions, 293 deletions
diff --git a/cpp/include/Ice/StreamTraits.h b/cpp/include/Ice/StreamTraits.h index 00f38cb5819..16dfe6a3963 100644 --- a/cpp/include/Ice/StreamTraits.h +++ b/cpp/include/Ice/StreamTraits.h @@ -20,28 +20,28 @@ namespace Ice // // The different types of Slice types supported by the stream -// marshalling/un-marshalling methods. +// marshaling/unmarshaling methods. // -enum StreamTraitType -{ - StreamTraitTypeBuiltin, - StreamTraitTypeStruct, - StreamTraitTypeStructClass, // struct with cpp:class metadata - StreamTraitTypeEnum, - StreamTraitTypeSequence, - StreamTraitTypeDictionary, - StreamTraitTypeProxy, - StreamTraitTypeClass, - StreamTraitTypeUserException, - StreamTraitTypeCustom -}; + +typedef int StreamTraitType; + +const StreamTraitType StreamTraitTypeUnknown = 0; +const StreamTraitType StreamTraitTypeBuiltin = 1; +const StreamTraitType StreamTraitTypeStruct = 2; +const StreamTraitType StreamTraitTypeStructClass = 3; // struct with cpp:class metadata +const StreamTraitType StreamTraitTypeEnum = 4; +const StreamTraitType StreamTraitTypeSequence = 5; +const StreamTraitType StreamTraitTypeDictionary = 6; +const StreamTraitType StreamTraitTypeProxy = 7; +const StreamTraitType StreamTraitTypeClass = 8; +const StreamTraitType StreamTraitTypeUserException = 9; // // The optional type. // // Optional data members or attribute is encoded with a specific // optional type. This optional type describes how the data is encoded -// and how it can be skipped by the un-marhsalling code if the optional +// and how it can be skipped by the unmarshaling code if the optional // isn't known to the receiver. // enum OptionalType @@ -96,11 +96,11 @@ struct IsMap // Base trait template. // Types with no specialized trait use this trait. // -template<typename T> +template<typename T, typename Enabler = void> struct StreamTrait { static const StreamTraitType type = IsMap<T>::value ? StreamTraitTypeDictionary : - (IsContainer<T>::value ? StreamTraitTypeSequence : StreamTraitTypeCustom); + (IsContainer<T>::value ? StreamTraitTypeSequence : StreamTraitTypeUnknown); // // When extracting a sequence<T> from a stream, we can ensure the @@ -123,7 +123,7 @@ struct StreamTrait template<typename T> struct IsFixedLength { - typedef typename StreamTrait<T> Traits; + typedef StreamTrait<T> Traits; static const bool value = (Traits::optionalType <= OptionalTypeF8) || ((Traits::type == StreamTraitTypeStruct || Traits::type == StreamTraitTypeStructClass) @@ -355,7 +355,7 @@ struct StreamHelper<T, StreamTraitTypeSequence> template<class S> static inline void read(S* stream, T& v) { - Int sz = stream->readAndCheckSeqSize(StreamTrait<T::value_type>::minWireSize); + Int sz = stream->readAndCheckSeqSize(StreamTrait<typename T::value_type>::minWireSize); T(sz).swap(v); for(typename T::iterator p = v.begin(); p != v.end(); ++p) { @@ -524,16 +524,26 @@ struct StreamOptionalHelper template<class S> static inline void write(S* stream, const T& v) { +#ifdef ICE_CPP11 + static_assert((ot != OptionalTypeVSize && ot != OptionalTypeFSize && ot != OptionalTypeEndMarker) + || st == StreamTraitTypeBuiltin, "Bad helper"); +#else assert((ot != OptionalTypeVSize && ot != OptionalTypeFSize && ot != OptionalTypeEndMarker) || st == StreamTraitTypeBuiltin); +#endif StreamHelper<T, st>::write(stream, v); } template<class S> static inline void read(S* stream, T& v) { +#ifdef ICE_CPP11 + static_assert((ot != OptionalTypeVSize && ot != OptionalTypeFSize && ot != OptionalTypeEndMarker) + || st == StreamTraitTypeBuiltin, "Bad helper"); +#else assert((ot != OptionalTypeVSize && ot != OptionalTypeFSize && ot != OptionalTypeEndMarker) || st == StreamTraitTypeBuiltin); +#endif StreamHelper<T, st>::read(stream, v); } }; @@ -568,7 +578,7 @@ struct StreamOptionalHelper<T, StreamTraitTypeStruct, OptionalTypeFSize> template<class S> static inline void write(S* stream, const T& v) { - stream->write((Int)0); + stream->write(static_cast<Int>(0)); typename S::size_type p = stream->pos(); stream->write(v); stream->rewrite(static_cast<Int>(stream->pos() - p), p - 4); diff --git a/cpp/include/Slice/CPlusPlusUtil.h b/cpp/include/Slice/CPlusPlusUtil.h index f738f5036c3..5911961e2aa 100644 --- a/cpp/include/Slice/CPlusPlusUtil.h +++ b/cpp/include/Slice/CPlusPlusUtil.h @@ -55,7 +55,6 @@ SLICE_API void writeAllocateCode(::IceUtilInternal::Output&, const ParamDeclList SLICE_API std::string getEndArg(const TypePtr&, const StringList&, const std::string&); SLICE_API void writeEndCode(::IceUtilInternal::Output&, const ParamDeclList&, const OperationPtr&); -SLICE_API std::string findMetaData(const SequencePtr&, const StringList&, bool&, int = 0); SLICE_API std::string findMetaData(const StringList&, int = 0); SLICE_API bool inWstringModule(const SequencePtr&); diff --git a/cpp/src/Slice/CPlusPlusUtil.cpp b/cpp/src/Slice/CPlusPlusUtil.cpp index 992ba303cda..83fb812cd20 100644 --- a/cpp/src/Slice/CPlusPlusUtil.cpp +++ b/cpp/src/Slice/CPlusPlusUtil.cpp @@ -106,12 +106,12 @@ sequenceTypeToString(const SequencePtr& seq, const StringList& metaData, int typ else { // Get the metadata associated at the point of definition. - bool protobuf; - seqType = findMetaData(seq, seq->getMetaData(), protobuf, typeCtx); - if(protobuf && !seqType.empty()) + seqType = findMetaData(seq->getMetaData(), typeCtx); + if(!seqType.empty()) { return seqType; } + return fixKwd(seq->scoped()); } } @@ -154,17 +154,12 @@ writeParamAllocateCode(Output& out, const TypePtr& type, bool optional, const st SequencePtr seq = SequencePtr::dynamicCast(type); if(seq) { - bool protobuf; - string seqType = findMetaData(seq, metaData, protobuf, typeCtx); - if(!protobuf && seqType.empty()) - { - seqType = findMetaData(seq, seq->getMetaData(), protobuf, typeCtx); - } - if(protobuf) + string seqType = findMetaData(metaData, typeCtx); + if(seqType.empty()) { - return; + seqType = findMetaData(seq->getMetaData(), typeCtx); } - + string s; if(seqType == "%array" || seqType == "%range:array") { @@ -197,76 +192,73 @@ writeParamEndCode(Output& out, const TypePtr& type, bool optional, const string& SequencePtr seq = SequencePtr::dynamicCast(type); if(seq) { - bool protobuf; - string seqType = findMetaData(seq, metaData, protobuf, TypeContextInParam); - if(!protobuf && seqType.empty()) + string seqType = findMetaData(metaData, TypeContextInParam); + if(seqType.empty()) { - seqType = findMetaData(seq, seq->getMetaData(), protobuf, TypeContextInParam); + seqType = findMetaData(seq->getMetaData(), TypeContextInParam); } - if(!protobuf) + + if(seqType == "%array" || seqType == "%range:array") { - if(seqType == "%array" || seqType == "%range:array") + BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type()); + if(builtin && + builtin->kind() != Builtin::KindByte && + builtin->kind() != Builtin::KindString && + builtin->kind() != Builtin::KindObject && + builtin->kind() != Builtin::KindObjectProxy) { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type()); - if(builtin && - builtin->kind() != Builtin::KindByte && - builtin->kind() != Builtin::KindString && - builtin->kind() != Builtin::KindObject && - builtin->kind() != Builtin::KindObjectProxy) + if(optional) { - if(optional) - { - out << nl << "if(___" << fixedName << ")"; - out << sb; - out << nl << fixedName << " = ___" << fixedName << "->second;"; + out << nl << "if(___" << fixedName << ")"; + out << sb; + out << nl << fixedName << " = ___" << fixedName << "->second;"; out << eb; - } - else - { - out << nl << fixedName << " = ___" << fixedName << ".second;"; - } } - else if(!builtin || - builtin->kind() == Builtin::KindString || - builtin->kind() == Builtin::KindObject || - builtin->kind() == Builtin::KindObjectProxy) + else { - if(optional) - { - out << nl << "if(___" << fixedName << ")"; - out << sb; - out << nl << fixedName << ".__setIsSet();"; - out << nl << fixedName << "->first" << " = &(*___" << fixedName << ")[0];"; - out << nl << fixedName << "->second" << " = " << fixedName << "->first + " << "___" - << fixedName << "->size();"; - out << eb; - } - else - { - out << nl << fixedName << ".first" << " = &___" << fixedName << "[0];"; - out << nl << fixedName << ".second" << " = " << fixedName << ".first + " << "___" - << fixedName << ".size();"; - } + out << nl << fixedName << " = ___" << fixedName << ".second;"; } } - else if(seqType.find("%range") == 0) + else if(!builtin || + builtin->kind() == Builtin::KindString || + builtin->kind() == Builtin::KindObject || + builtin->kind() == Builtin::KindObjectProxy) { if(optional) { out << nl << "if(___" << fixedName << ")"; out << sb; out << nl << fixedName << ".__setIsSet();"; - out << nl << fixedName << "->first = (*___" << fixedName << ").begin();"; - out << nl << fixedName << "->second = (*___" << fixedName << ").end();"; + out << nl << fixedName << "->first" << " = &(*___" << fixedName << ")[0];"; + out << nl << fixedName << "->second" << " = " << fixedName << "->first + " << "___" + << fixedName << "->size();"; out << eb; } else { - out << nl << fixedName << ".first = ___" << fixedName << ".begin();"; - out << nl << fixedName << ".second = ___" << fixedName << ".end();"; + out << nl << fixedName << ".first" << " = &___" << fixedName << "[0];"; + out << nl << fixedName << ".second" << " = " << fixedName << ".first + " << "___" + << fixedName << ".size();"; } } } + else if(seqType.find("%range") == 0) + { + if(optional) + { + out << nl << "if(___" << fixedName << ")"; + out << sb; + out << nl << fixedName << ".__setIsSet();"; + out << nl << fixedName << "->first = (*___" << fixedName << ").begin();"; + out << nl << fixedName << "->second = (*___" << fixedName << ").end();"; + out << eb; + } + else + { + out << nl << fixedName << ".first = ___" << fixedName << ".begin();"; + out << nl << fixedName << ".second = ___" << fixedName << ".end();"; + } + } } } @@ -962,40 +954,37 @@ Slice::getEndArg(const TypePtr& type, const StringList& metaData, const string& SequencePtr seq = SequencePtr::dynamicCast(type); if(seq) { - bool protobuf; - string seqType = findMetaData(seq, metaData, protobuf, TypeContextInParam); - if(!protobuf && seqType.empty()) + string seqType = findMetaData(metaData, TypeContextInParam); + if(seqType.empty()) { - seqType = findMetaData(seq, seq->getMetaData(), protobuf, TypeContextInParam); + seqType = findMetaData(seq->getMetaData(), TypeContextInParam); } - if(!protobuf) + + if(seqType == "%array" || seqType == "%range:array") { - if(seqType == "%array" || seqType == "%range:array") + BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type()); + if(builtin && + builtin->kind() != Builtin::KindByte && + builtin->kind() != Builtin::KindString && + builtin->kind() != Builtin::KindObject && + builtin->kind() != Builtin::KindObjectProxy) { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type()); - if(builtin && - builtin->kind() != Builtin::KindByte && - builtin->kind() != Builtin::KindString && - builtin->kind() != Builtin::KindObject && - builtin->kind() != Builtin::KindObjectProxy) - { - endArg = "___" + endArg; - } - else if(!builtin || builtin->kind() != Builtin::KindByte) - { - endArg = "___" + endArg; - } + endArg = "___" + endArg; } - else if(seqType.find("%range") == 0) + else if(!builtin || builtin->kind() != Builtin::KindByte) { - StringList md; - if(seqType.find("%range:") == 0) - { - md.push_back("cpp:type:" + seqType.substr(strlen("%range:"))); - } endArg = "___" + endArg; } } + else if(seqType.find("%range") == 0) + { + StringList md; + if(seqType.find("%range:") == 0) + { + md.push_back("cpp:type:" + seqType.substr(strlen("%range:"))); + } + endArg = "___" + endArg; + } } return endArg; } @@ -1013,99 +1002,6 @@ Slice::writeEndCode(Output& out, const ParamDeclList& params, const OperationPtr } } -// Accepted metadata. -// -// cpp:type:<typename> -// cpp:const -// cpp:array -// cpp:range:<typename> -// cpp:protobuf<:typename> -// -// For the new AMI mapping, we ignore the array and range directives because they don't apply. -// -// This form is for sequences definitions only. -// -string -Slice::findMetaData(const SequencePtr& seq, const StringList& metaData, bool& isProtobuf, int typeCtx) -{ - isProtobuf = false; - static const string prefix = "cpp:"; - for(StringList::const_iterator q = metaData.begin(); q != metaData.end(); ++q) - { - string str = *q; - if(str.find(prefix) == 0) - { - string::size_type pos = str.find(':', prefix.size()); - string ss = str.substr(prefix.size()); - - // - // If the form is cpp:type:<...> the data after cpp:type: - // is returned. - // If the form is cpp:range[:<...>], cpp:array or cpp:class, - // the return value is % followed by the string after cpp:. - // - if(ss.find("protobuf") == 0 || pos != string::npos) - { - if(ss.find("type:") == 0) - { - return str.substr(pos + 1); - } - else if(ss.find("protobuf:") == 0) - { - BuiltinPtr builtin = BuiltinPtr::dynamicCast(seq->type()); - if(!builtin || builtin->kind() != Builtin::KindByte) - { - continue; - } - isProtobuf = true; - if(pos != string::npos) - { - return str.substr(pos + 1); - } - return ""; - } - else if((typeCtx & (TypeContextInParam | TypeContextAMIPrivateEnd)) && - !(typeCtx & TypeContextAMIEnd) && ss.find("range:") == 0) - { - return string("%") + str.substr(prefix.size()); - } - else if((typeCtx & TypeContextAMIPrivateEnd) && ss == "range:array") - { - return "%range:array"; - } - } - // - // If the data is an inParam and the metadata is cpp:array - // or cpp:range then array or range is returned. - // - else if(typeCtx & (TypeContextInParam | TypeContextAMIPrivateEnd) && !(typeCtx & TypeContextAMIEnd)) - { - if(ss == "array") - { - return "%array"; - } - else if((typeCtx & TypeContextInParam) && ss == "range") - { - return "%range"; - } - } - // - // Otherwise if the data is "class" it is returned. - // - else - { - if(ss == "class") - { - return "%class"; - } - } - } - } - - return ""; -} - -// Does not handle cpp:protobuf string Slice::findMetaData(const StringList& metaData, int typeCtx) { @@ -1126,7 +1022,7 @@ Slice::findMetaData(const StringList& metaData, int typeCtx) if(pos != string::npos) { string ss = str.substr(prefix.size()); - if(ss.find("type:") == 0) + if(ss.find("type:") == 0 || ss.find("protobuf:") == 0) { return str.substr(pos + 1); } diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp index e7477b1bd95..d67d8aa3256 100644 --- a/cpp/src/slice2cpp/Gen.cpp +++ b/cpp/src/slice2cpp/Gen.cpp @@ -1332,27 +1332,6 @@ void Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p) { string name = fixKwd(p->name()); - TypePtr type = p->type(); - if(p->container() != 0 && - (StructPtr::dynamicCast(p->container()) || ExceptionPtr::dynamicCast(p->container())) && - SequencePtr::dynamicCast(type)) - { - SequencePtr s = SequencePtr::dynamicCast(type); - BuiltinPtr builtin = BuiltinPtr::dynamicCast(s->type()); - if(builtin && builtin->kind() == Builtin::KindByte) - { - StringList metaData = s->getMetaData(); - bool protobuf; - findMetaData(s, metaData, protobuf); - if(protobuf) - { - emitWarning(p->file(), p->line(), string("protobuf cannot be used as a ") + - (StructPtr::dynamicCast(p->container()) ? "struct" : "exception") + - " member in C++"); - } - } - } - H << nl << typeToString(p->type(), p->optional(), p->getMetaData(), _useWstring) << ' ' << name << ';'; } @@ -1364,19 +1343,16 @@ Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p) string s = typeToString(type, p->typeMetaData(), _useWstring); StringList metaData = p->getMetaData(); - bool protobuf; - string seqType = findMetaData(p, metaData, protobuf); + string seqType = findMetaData(metaData, _useWstring); H << sp; - if(!protobuf) + + if(!seqType.empty()) { - if(!seqType.empty()) - { - H << nl << "typedef " << seqType << ' ' << name << ';'; - } - else - { - H << nl << "typedef ::std::vector<" << (s[0] == ':' ? " " : "") << s << "> " << name << ';'; - } + H << nl << "typedef " << seqType << ' ' << name << ';'; + } + else + { + H << nl << "typedef ::std::vector<" << (s[0] == ':' ? " " : "") << s << "> " << name << ';'; } } @@ -1393,22 +1369,6 @@ Slice::Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p) // TypePtr keyType = p->keyType(); - if(SequencePtr::dynamicCast(keyType)) - { - SequencePtr s = SequencePtr::dynamicCast(keyType); - BuiltinPtr builtin = BuiltinPtr::dynamicCast(s->type()); - if(builtin && builtin->kind() == Builtin::KindByte) - { - StringList metaData = s->getMetaData(); - bool protobuf; - findMetaData(s, metaData, protobuf); - if(protobuf) - { - emitWarning(p->file(), p->line(), "protobuf cannot be used as a dictionary key in C++"); - } - } - } - TypePtr valueType = p->valueType(); string ks = typeToString(keyType, p->keyMetaData(), _useWstring); if(ks[0] == ':') @@ -4531,24 +4491,7 @@ Slice::Gen::ObjectVisitor::visitOperation(const OperationPtr& p) void Slice::Gen::ObjectVisitor::emitDataMember(const DataMemberPtr& p) -{ - TypePtr type = p->type(); - if(SequencePtr::dynamicCast(type)) - { - SequencePtr s = SequencePtr::dynamicCast(type); - BuiltinPtr builtin = BuiltinPtr::dynamicCast(s->type()); - if(builtin && builtin->kind() == Builtin::KindByte) - { - StringList metaData = s->getMetaData(); - bool protobuf; - findMetaData(s, metaData, protobuf); - if(protobuf) - { - emitWarning(p->file(), p->line(), "protobuf cannot be used as a class member in C++"); - } - } - } - +{ string name = fixKwd(p->name()); H << sp << nl << typeToString(p->type(), p->optional(), p->getMetaData(), _useWstring) << ' ' << name << ';'; } @@ -6366,34 +6309,7 @@ Slice::Gen::MetaDataVisitor::visitDataMember(const DataMemberPtr& p) void Slice::Gen::MetaDataVisitor::visitSequence(const SequencePtr& p) { - StringList metaData = p->getMetaData(); - const string file = p->file(); - const string line = p->line(); - static const string prefix = "cpp:protobuf"; - for(StringList::const_iterator q = metaData.begin(); q != metaData.end(); ) - { - string s = *q++; - if(_history.count(s) == 0) - { - if(s.find(prefix) == 0) - { - // - // Remove from list so validate does not try to handle as well. - // - metaData.remove(s); - - BuiltinPtr builtin = BuiltinPtr::dynamicCast(p->type()); - if(!builtin || builtin->kind() != Builtin::KindByte) - { - _history.insert(s); - emitWarning(file, line, "ignoring invalid metadata `" + s + "':\n"+ - "`protobuf' encoding must be a byte sequence."); - } - } - } - } - - validate(p, metaData, file, line); + validate(p, p->getMetaData(), p->file(), p->line()); } void |