protected override QilNode VisitElementCtor(QilBinary ndElem) {
XmlILConstructInfo info = XmlILConstructInfo.Read(ndElem);
bool callChk;
GenerateNameType nameType;
Debug.Assert(XmlILConstructInfo.Read(ndElem).PushToWriterFirst, "Element contruction should always be pushed to writer.");
// Runtime checks must be made in the following cases:
// 1. Xml state is not known at compile-time, or is illegal
// 2. Element's namespace must be declared
// 3. Element's attributes might be duplicates of one another, or namespaces might follow attributes
callChk = CheckWithinContent(info) || !info.IsNamespaceInScope || ElementCachesAttributes(info);
// If it is not known whether element content was output, then make this check at run-time
if (XmlILConstructInfo.Read(ndElem.Right).FinalStates == PossibleXmlStates.Any)
callChk = true;
// If runtime state after EndElement is called is not known, then call XmlQueryOutput.WriteEndElementChk
if (info.FinalStates == PossibleXmlStates.Any)
callChk = true;
// If WriteStartElementChk will *not* be called, then code must be generated to ensure valid state transitions
if (!callChk)
BeforeStartChecks(ndElem);
// Generate call to WriteStartElement
nameType = LoadNameAndType(XPathNodeType.Element, ndElem.Left, true, callChk);
this.helper.CallWriteStartElement(nameType, callChk);
// Recursively construct content
NestedVisit(ndElem.Right);
// If runtime state is guaranteed to be EnumAttrs, and an element is being constructed, call XmlQueryOutput.StartElementContent
if (XmlILConstructInfo.Read(ndElem.Right).FinalStates == PossibleXmlStates.EnumAttrs && !callChk)
this.helper.CallStartElementContent();
// Generate call to WriteEndElement
nameType = LoadNameAndType(XPathNodeType.Element, ndElem.Left, false, callChk);
this.helper.CallWriteEndElement(nameType, callChk);
if (!callChk)
AfterEndChecks(ndElem);
this.iterCurr.Storage = StorageDescriptor.None();
return ndElem;
}