From 7e6e3d20f334547d8cea78e8e0b37106efebe028 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 8 Nov 2011 13:48:38 -0800 Subject: added Lazy modifier to params to support recursion ChoiceBlock can now derive from another param block Params with name/value support can be assigned directly in C++ code using param = "named_value" --- indra/llxuixml/llxuiparser.cpp | 258 +++++++++++++++++++++++++++++++---------- 1 file changed, 197 insertions(+), 61 deletions(-) (limited to 'indra/llxuixml/llxuiparser.cpp') diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp index 878f992178..cdf578113a 100644 --- a/indra/llxuixml/llxuiparser.cpp +++ b/indra/llxuixml/llxuiparser.cpp @@ -59,28 +59,26 @@ const char* NO_VALUE_MARKER = "no_value"; const S32 LINE_NUMBER_HERE = 0; -struct MaxOccur : public LLInitParam::ChoiceBlock +struct MaxOccursValues : public LLInitParam::TypeValuesHelper { - Alternative count; - Alternative unbounded; - - MaxOccur() - : unbounded("", "unbounded") - {} + using TypeValuesHelper::operator =; + typedef std::string name_t; + static void declareValues() + { + declare("unbounded", U32_MAX); + } }; struct Occurs : public LLInitParam::Block { - Optional minOccurs; - Optional maxOccurs; + Optional minOccurs; + Optional maxOccurs; + Multiple foo; Occurs() - : minOccurs("minOccurs"), - maxOccurs("maxOccurs") - { - minOccurs = 0; - maxOccurs.unbounded.choose(); - } + : minOccurs("minOccurs", 0), + maxOccurs("maxOccurs", U32_MAX) + {} }; @@ -103,18 +101,15 @@ namespace LLInitParam }; } -struct Name : public LLInitParam::Block -{ - Mandatory name; - - Name() - : name("name") - {} -}; +struct Element; +struct Group; +struct Choice; +struct Sequence; +struct Any; struct Attribute : public LLInitParam::Block { - Mandatory name; + Mandatory name; Mandatory type; Mandatory use; @@ -122,41 +117,170 @@ struct Attribute : public LLInitParam::Block : name("name"), type("type"), use("use") + {} +}; + +struct Any : public LLInitParam::Block +{ + Optional _namespace; + + Any() + : _namespace("namespace") + {} +}; + +struct All : public LLInitParam::Block +{ + Multiple> elements; + + All() + : elements("element") { + maxOccurs = 1; } }; -struct ComplexType : public LLInitParam::Block +struct Choice : public LLInitParam::ChoiceBlock +{ + Alternative> element; + Alternative> group; + Alternative> choice; + Alternative> sequence; + Alternative> any; + + Choice() + : element("element"), + group("group"), + choice("choice"), + sequence("sequence"), + any("any") + {} + +}; + +struct Sequence : public LLInitParam::ChoiceBlock +{ + Alternative> element; + Alternative> group; + Alternative> choice; + Alternative> sequence; + Alternative> any; +}; + +struct GroupContents : public LLInitParam::ChoiceBlock { - Multiple attribute; - //Multiple elements; - Optional mixed; + Alternative all; + Alternative choice; + Alternative sequence; + + GroupContents() + : all("all"), + choice("choice"), + sequence("sequence") + {} +}; + +struct Group : public LLInitParam::Block +{ + Optional name, + ref; + + Group() + : name("name"), + ref("ref") + {} +}; + +struct Restriction : public LLInitParam::Block +{ +}; + +struct Extension : public LLInitParam::Block +{ +}; + +struct SimpleContent : public LLInitParam::ChoiceBlock +{ + Alternative restriction; + Alternative extension; + + SimpleContent() + : restriction("restriction"), + extension("extension") + {} +}; + +struct SimpleType : public LLInitParam::Block +{ + // TODO +}; + +struct ComplexContent : public LLInitParam::Block +{ + Optional mixed; + + ComplexContent() + : mixed("mixed", true) + {} +}; + +struct ComplexTypeContents : public LLInitParam::ChoiceBlock +{ + Alternative simple_content; + Alternative complex_content; + Alternative group; + Alternative all; + Alternative choice; + Alternative sequence; + + ComplexTypeContents() + : simple_content("simpleContent"), + complex_content("complexContent"), + group("group"), + all("all"), + choice("choice"), + sequence("sequence") + {} +}; + +struct ComplexType : public LLInitParam::Block +{ + Optional name; + Optional mixed; + + Multiple attribute; + Multiple> elements; ComplexType() - : attribute("xs:attribute"), - //elements("xs:element"), + : name("name"), + attribute("xs:attribute"), + elements("xs:element"), mixed("mixed") { - mixed = true; } }; -struct Element : public LLInitParam::Block +struct ElementContents : public LLInitParam::ChoiceBlock { - Mandatory complexType; - Mandatory name; + Alternative simpleType; + Alternative complexType; - Element() - : complexType("xs:complexType") + ElementContents() + : simpleType("simpleType"), + complexType("complexType") {} }; -struct Elements : public LLInitParam::Block +struct Element : public LLInitParam::Block { - Multiple elements; + Optional name, + ref, + type; - Elements() - : elements("xs:element") + Element() + : name("xs:name"), + ref("xs:ref"), + type("xs:type") {} }; @@ -164,28 +288,32 @@ struct Schema : public LLInitParam::Block { private: Mandatory targetNamespace, - xmlns; + xmlns, + xs; public: Optional attributeFormDefault, - elementFormDefault, - xs; + elementFormDefault; - Optional elements; + Mandatory root_element; void setNameSpace(const std::string& ns) {targetNamespace = ns; xmlns = ns;} - Schema() + Schema(const std::string& ns = LLStringUtil::null) : attributeFormDefault("attributeFormDefault"), elementFormDefault("elementFormDefault"), xs("xmlns:xs"), targetNamespace("targetNamespace"), xmlns("xmlns"), - elements("xs:choice") + root_element("xs:element") { attributeFormDefault = "unqualified"; elementFormDefault = "qualified"; xs = "http://www.w3.org/2001/XMLSchema"; + if (!ns.empty()) + { + setNameSpace(ns); + }; } }; @@ -214,22 +342,30 @@ LLXSDWriter::LLXSDWriter() void LLXSDWriter::writeXSD(const std::string& type_name, LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const std::string& xml_namespace) { + Schema schema(xml_namespace); + + schema.root_element.name = type_name; + Choice& choice = schema.root_element.complexType.choice; + + choice.minOccurs = 0; + choice.maxOccurs = "unbounded"; + mSchemaNode = node; - node->setName("xs:schema"); - node->createChild("attributeFormDefault", true)->setStringValue("unqualified"); - node->createChild("elementFormDefault", true)->setStringValue("qualified"); - node->createChild("targetNamespace", true)->setStringValue(xml_namespace); - node->createChild("xmlns:xs", true)->setStringValue("http://www.w3.org/2001/XMLSchema"); - node->createChild("xmlns", true)->setStringValue(xml_namespace); - - node = node->createChild("xs:complexType", false); - node->createChild("name", true)->setStringValue(type_name); - node->createChild("mixed", true)->setStringValue("true"); - - mAttributeNode = node; - mElementNode = node->createChild("xs:choice", false); - mElementNode->createChild("minOccurs", true)->setStringValue("0"); - mElementNode->createChild("maxOccurs", true)->setStringValue("unbounded"); + //node->setName("xs:schema"); + //node->createChild("attributeFormDefault", true)->setStringValue("unqualified"); + //node->createChild("elementFormDefault", true)->setStringValue("qualified"); + //node->createChild("targetNamespace", true)->setStringValue(xml_namespace); + //node->createChild("xmlns:xs", true)->setStringValue("http://www.w3.org/2001/XMLSchema"); + //node->createChild("xmlns", true)->setStringValue(xml_namespace); + + //node = node->createChild("xs:complexType", false); + //node->createChild("name", true)->setStringValue(type_name); + //node->createChild("mixed", true)->setStringValue("true"); + + //mAttributeNode = node; + //mElementNode = node->createChild("xs:choice", false); + //mElementNode->createChild("minOccurs", true)->setStringValue("0"); + //mElementNode->createChild("maxOccurs", true)->setStringValue("unbounded"); block.inspectBlock(*this); // duplicate element choices -- cgit v1.3 From 2ee4bae1a39814467e4bd361211f7836266af880 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 16 Nov 2011 12:28:10 -0800 Subject: support for assignment of named values to params, works with string-typed params as well as () operator --- indra/llxuixml/llinitparam.h | 93 +++++++++++++++++++++++++++++++++++------- indra/llxuixml/llxuiparser.cpp | 4 +- 2 files changed, 80 insertions(+), 17 deletions(-) (limited to 'indra/llxuixml/llxuiparser.cpp') diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h index ec14bc2fdc..575e8231bd 100644 --- a/indra/llxuixml/llinitparam.h +++ b/indra/llxuixml/llinitparam.h @@ -572,7 +572,7 @@ namespace LLInitParam static bool equals(const BaseBlock::Lazy& a, const BaseBlock::Lazy& b) { return !a.empty() || !b.empty(); } }; - class Param + class Param { public: void setProvided(bool is_provided = true) @@ -580,6 +580,12 @@ namespace LLInitParam mIsProvided = is_provided; enclosingBlock().paramChanged(*this, is_provided); } + + Param& operator =(const Param& other) + { + setProvided(other.mIsProvided); + return *this; + } protected: bool anyProvided() const { return mIsProvided; } @@ -671,7 +677,7 @@ namespace LLInitParam self_t& operator =(const self_t& other) { mValue = other.mValue; - static_cast(*this) = other; + NAME_VALUE_LOOKUP::operator =(other); return *this; } @@ -742,8 +748,8 @@ namespace LLInitParam self_t& operator =(const self_t& other) { - static_cast(*this) = other; - static_cast(*this) = other; + T::operator = (other); + NAME_VALUE_LOOKUP::operator =(other); mValidatedVersion = other.mValidatedVersion; mValidated = other.mValidated; return *this; @@ -753,6 +759,54 @@ namespace LLInitParam mutable bool mValidated; // lazy validation flag }; + template + class ParamValue + : public NAME_VALUE_LOOKUP + { + public: + typedef const std::string& value_assignment_t; + typedef ParamValue self_t; + + ParamValue(): mValue() {} + ParamValue(value_assignment_t other) : mValue(other) {} + + void setValue(value_assignment_t val) + { + if (NAME_VALUE_LOOKUP::getValueFromName(val, mValue)) + { + setValueName(val); + } + else + { + mValue = val; + } + } + + value_assignment_t getValue() const + { + return mValue; + } + + std::string& getValue() + { + return mValue; + } + + operator value_assignment_t() const + { + return mValue; + } + + value_assignment_t operator()() const + { + return mValue; + } + + protected: + std::string mValue; + }; + + template > struct ParamIterator { @@ -776,6 +830,8 @@ namespace LLInitParam typedef NAME_VALUE_LOOKUP name_value_lookup_t; typedef ParamValue param_value_t; + using param_value_t::operator(); + TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) : Param(block_descriptor.mCurrentBlockPtr) { @@ -877,11 +933,6 @@ namespace LLInitParam } } - self_t& operator =(typename const name_value_lookup_t::name_t& name) - { - return static_cast(param_value_t::operator =(name)); - } - void set(value_assignment_t val, bool flag_as_provided = true) { param_value_t::clearValueName(); @@ -889,6 +940,11 @@ namespace LLInitParam setProvided(flag_as_provided); } + self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name) + { + return static_cast(param_value_t::operator =(name)); + } + protected: static bool mergeWith(Param& dst, const Param& src, bool overwrite) { @@ -919,6 +975,8 @@ namespace LLInitParam typedef NAME_VALUE_LOOKUP name_value_lookup_t; typedef ParamValue param_value_t; + using param_value_t::operator(); + TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) : Param(block_descriptor.mCurrentBlockPtr), param_value_t(value) @@ -1023,6 +1081,11 @@ namespace LLInitParam setProvided(flag_as_provided); } + self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name) + { + return static_cast(param_value_t::operator =(name)); + } + // propagate changed status up to enclosing block /*virtual*/ void paramChanged(const Param& changed_param, bool user_provided) { @@ -1189,7 +1252,9 @@ namespace LLInitParam void add(const value_t& item) { - mValues.push_back(param_value_t(item)); + param_value_t param_value; + param_value.setValue(item); + mValues.push_back(param_value); setProvided(); } @@ -1537,7 +1602,7 @@ namespace LLInitParam typedef TypedParam >::value> super_t; typedef typename super_t::value_assignment_t value_assignment_t; - using super_t::param_value_t::operator =; + using super_t::operator =; explicit Alternative(const char* name = "", value_assignment_t val = defaultValue()) : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1), @@ -1656,8 +1721,8 @@ namespace LLInitParam typedef typename super_t::value_assignment_t value_assignment_t; using super_t::operator(); - using super_t::param_value_t::operator =; - + using super_t::operator =; + explicit Optional(const char* name = "", value_assignment_t val = defaultValue()) : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1) { @@ -1686,7 +1751,7 @@ namespace LLInitParam typedef typename super_t::value_assignment_t value_assignment_t; using super_t::operator(); - using super_t::param_value_t::operator =; + using super_t::operator =; // mandatory parameters require a name to be parseable explicit Mandatory(const char* name = "", value_assignment_t val = defaultValue()) diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp index cdf578113a..90c2671242 100644 --- a/indra/llxuixml/llxuiparser.cpp +++ b/indra/llxuixml/llxuiparser.cpp @@ -61,8 +61,6 @@ const S32 LINE_NUMBER_HERE = 0; struct MaxOccursValues : public LLInitParam::TypeValuesHelper { - using TypeValuesHelper::operator =; - typedef std::string name_t; static void declareValues() { declare("unbounded", U32_MAX); @@ -73,11 +71,11 @@ struct Occurs : public LLInitParam::Block { Optional minOccurs; Optional maxOccurs; - Multiple foo; Occurs() : minOccurs("minOccurs", 0), maxOccurs("maxOccurs", U32_MAX) + {} }; -- cgit v1.3 From 2851cd519338ef4a1fde15da8d4015ab4380d6cb Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Mon, 28 Nov 2011 11:33:49 -0700 Subject: a try fix for sh-2651: [crashhunters] Crash after google translate failure and sh-2658: crash in LLPluginMessage::parse --- indra/llprimitive/llvolumexml.cpp | 19 +++++++++++-------- indra/llprimitive/llvolumexml.h | 6 +++--- indra/llui/llui.cpp | 7 +++++-- indra/llxml/llxmlnode.cpp | 8 ++++---- indra/llxuixml/llxuiparser.cpp | 1 + indra/newview/llvoicevivox.cpp | 1 - 6 files changed, 24 insertions(+), 18 deletions(-) (limited to 'indra/llxuixml/llxuiparser.cpp') diff --git a/indra/llprimitive/llvolumexml.cpp b/indra/llprimitive/llvolumexml.cpp index f4f9d4d713..bf2297a029 100644 --- a/indra/llprimitive/llvolumexml.cpp +++ b/indra/llprimitive/llvolumexml.cpp @@ -34,9 +34,9 @@ //============================================================================ -LLXMLNode *LLVolumeXml::exportProfileParams(const LLProfileParams* params) +LLPointer LLVolumeXml::exportProfileParams(const LLProfileParams* params) { - LLXMLNode *ret = new LLXMLNode("profile", FALSE); + LLPointer ret = new LLXMLNode("profile", FALSE); ret->createChild("curve_type", TRUE)->setByteValue(1, ¶ms->getCurveType()); ret->createChild("interval", FALSE)->setFloatValue(2, ¶ms->getBegin()); @@ -46,9 +46,9 @@ LLXMLNode *LLVolumeXml::exportProfileParams(const LLProfileParams* params) } -LLXMLNode *LLVolumeXml::exportPathParams(const LLPathParams* params) +LLPointer LLVolumeXml::exportPathParams(const LLPathParams* params) { - LLXMLNode *ret = new LLXMLNode("path", FALSE); + LLPointer ret = new LLXMLNode("path", FALSE); ret->createChild("curve_type", TRUE)->setByteValue(1, ¶ms->getCurveType()); ret->createChild("interval", FALSE)->setFloatValue(2, ¶ms->getBegin()); ret->createChild("scale", FALSE)->setFloatValue(2, params->getScale().mV); @@ -63,12 +63,15 @@ LLXMLNode *LLVolumeXml::exportPathParams(const LLPathParams* params) } -LLXMLNode *LLVolumeXml::exportVolumeParams(const LLVolumeParams* params) +LLPointer LLVolumeXml::exportVolumeParams(const LLVolumeParams* params) { - LLXMLNode *ret = new LLXMLNode("shape", FALSE); + LLPointer ret = new LLXMLNode("shape", FALSE); - exportPathParams(¶ms->getPathParams())->setParent(ret); - exportProfileParams(¶ms->getProfileParams())->setParent(ret); + LLPointer node ; + node = exportPathParams(¶ms->getPathParams()) ; + node->setParent(ret); + node = exportProfileParams(¶ms->getProfileParams()) ; + node->setParent(ret); return ret; } diff --git a/indra/llprimitive/llvolumexml.h b/indra/llprimitive/llvolumexml.h index 5e79205d9a..9d4d989475 100644 --- a/indra/llprimitive/llvolumexml.h +++ b/indra/llprimitive/llvolumexml.h @@ -34,11 +34,11 @@ class LLVolumeXml { public: - static LLXMLNode* exportProfileParams(const LLProfileParams* params); + static LLPointer exportProfileParams(const LLProfileParams* params); - static LLXMLNode* exportPathParams(const LLPathParams* params); + static LLPointer exportPathParams(const LLPathParams* params); - static LLXMLNode* exportVolumeParams(const LLVolumeParams* params); + static LLPointer exportVolumeParams(const LLVolumeParams* params); }; #endif // LL_LLVOLUMEXML_H diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 79ad99a770..69461ec099 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -1823,9 +1823,12 @@ void LLUI::setupPaths() LLXMLNodePtr root; BOOL success = LLXMLNode::parseFile(filename, root, NULL); Paths paths; - LLXUIParser parser; - parser.readXUI(root, paths, filename); + if(success) + { + LLXUIParser parser; + parser.readXUI(root, paths, filename); + } sXUIPaths.clear(); if (success && paths.validateBlock()) diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index 4362c88c4e..2b4a0fc2a1 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -693,7 +693,7 @@ bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXML LLFILE* fp = LLFile::fopen(filename, "rb"); /* Flawfinder: ignore */ if (fp == NULL) { - node = new LLXMLNode(); + node = NULL ; return false; } fseek(fp, 0, SEEK_END); @@ -746,7 +746,7 @@ bool LLXMLNode::parseBuffer( { llwarns << "Parse failure - wrong number of top-level nodes xml." << llendl; - node = new LLXMLNode(); + node = NULL ; return false; } @@ -805,7 +805,7 @@ bool LLXMLNode::parseStream( { llwarns << "Parse failure - wrong number of top-level nodes xml." << llendl; - node = new LLXMLNode(); + node = NULL; return false; } @@ -1206,7 +1206,7 @@ bool LLXMLNode::getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, BOO { return mDefault->getChild(name, node, FALSE); } - node = new LLXMLNode(); + node = NULL; return false; } diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp index 878f992178..5a525f84a8 100644 --- a/indra/llxuixml/llxuiparser.cpp +++ b/indra/llxuixml/llxuiparser.cpp @@ -1247,6 +1247,7 @@ bool LLSimpleXUIParser::readXUI(const std::string& filename, LLInitParam::BaseBl if( !file.isOpen() ) { LL_WARNS("ReadXUI") << "Unable to open file " << filename << LL_ENDL; + XML_ParserFree( mParser ); return false; } diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 8ecf4a80b7..2d7437f4f3 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -7020,7 +7020,6 @@ void LLVivoxVoiceClient::captureBufferPlayStopSendMessage() LLVivoxProtocolParser::LLVivoxProtocolParser() { - parser = NULL; parser = XML_ParserCreate(NULL); reset(); -- cgit v1.3 From 770538f992a42cdda091f93e8b318e35372aaad2 Mon Sep 17 00:00:00 2001 From: Leslie Linden Date: Thu, 1 Dec 2011 10:42:15 -0800 Subject: Build fixes for mac, hopefully Linux too --- indra/llui/llhandle.h | 2 +- indra/llxuixml/llinitparam.h | 2 +- indra/llxuixml/llxuiparser.cpp | 24 ++++++++++++------------ 3 files changed, 14 insertions(+), 14 deletions(-) (limited to 'indra/llxuixml/llxuiparser.cpp') diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h index e6390ee599..37c657dd92 100644 --- a/indra/llui/llhandle.h +++ b/indra/llui/llhandle.h @@ -166,7 +166,7 @@ protected: } template - typename LLHandle getDerivedHandle(typename boost::enable_if< typename boost::is_convertible >::type* dummy = 0) const + LLHandle getDerivedHandle(typename boost::enable_if< typename boost::is_convertible >::type* dummy = 0) const { LLHandle downcast_handle; downcast_handle.mTombStone = getHandle().mTombStone; diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h index 7927f84cba..ab20957760 100644 --- a/indra/llxuixml/llinitparam.h +++ b/indra/llxuixml/llinitparam.h @@ -764,7 +764,7 @@ namespace LLInitParam { if (NAME_VALUE_LOOKUP::getValueFromName(val, mValue)) { - setValueName(val); + NAME_VALUE_LOOKUP::setValueName(val); } else { diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp index 90c2671242..58654dcc21 100644 --- a/indra/llxuixml/llxuiparser.cpp +++ b/indra/llxuixml/llxuiparser.cpp @@ -129,7 +129,7 @@ struct Any : public LLInitParam::Block struct All : public LLInitParam::Block { - Multiple> elements; + Multiple< Lazy > elements; All() : elements("element") @@ -140,11 +140,11 @@ struct All : public LLInitParam::Block struct Choice : public LLInitParam::ChoiceBlock { - Alternative> element; - Alternative> group; - Alternative> choice; - Alternative> sequence; - Alternative> any; + Alternative< Lazy > element; + Alternative< Lazy > group; + Alternative< Lazy > choice; + Alternative< Lazy > sequence; + Alternative< Lazy > any; Choice() : element("element"), @@ -158,11 +158,11 @@ struct Choice : public LLInitParam::ChoiceBlock struct Sequence : public LLInitParam::ChoiceBlock { - Alternative> element; - Alternative> group; - Alternative> choice; - Alternative> sequence; - Alternative> any; + Alternative< Lazy > element; + Alternative< Lazy > group; + Alternative< Lazy > choice; + Alternative< Lazy > sequence; + Alternative< Lazy > any; }; struct GroupContents : public LLInitParam::ChoiceBlock @@ -247,7 +247,7 @@ struct ComplexType : public LLInitParam::Block Optional mixed; Multiple attribute; - Multiple> elements; + Multiple< Lazy > elements; ComplexType() : name("name"), -- cgit v1.3