bool SymbolClassName::setBitSizeOfClassInstances() { bool aok = true; NodeBlockClass * classNode = getClassBlockNode(); assert(classNode); //infinite loop "Incomplete Class <> was never defined, fails sizing" m_state.pushClassContext(getUlamTypeIdx(), classNode, classNode, false, NULL); s32 totalbits = 0; aok = SymbolClass::trySetBitsizeWithUTIValues(totalbits); if(aok) { UTI cuti = getUlamTypeIdx(); m_state.setBitSize(cuti, totalbits); //"scalar" Class bitsize KEY ADJUSTED if(m_state.getBitSize(cuti) != totalbits) { std::ostringstream msg; msg << "CLASS (regular) '" << m_state.getUlamTypeNameByIndex(cuti).c_str(); msg << "' SIZED " << totalbits << " FAILED"; MSG(Symbol::getTokPtr(), msg.str().c_str(),ERR); classNode->setNodeType(Nav); //avoid assert in resolving loop } else { std::ostringstream msg; msg << "CLASS (regular) '" << m_state.getUlamTypeNameByIndex(cuti).c_str(); msg << "' SIZED: " << totalbits; MSG(Symbol::getTokPtr(), msg.str().c_str(),DEBUG); } } m_state.popClassContext(); //restore return aok; } //setBitSizeOfClassInstances
void SymbolClassName::resetUnseenClassLocation(Token identTok) { //during parsing Symbol::resetIdToken(identTok); NodeBlockClass * classNode = getClassBlockNode(); assert(classNode); classNode->setNodeLocation(identTok.m_locator); } //resetUnseenClassLocation
void SymbolClassName::packBitsForClassInstances() { NodeBlockClass * classNode = getClassBlockNode(); assert(classNode); m_state.pushClassContext(getUlamTypeIdx(), classNode, classNode, false, NULL); classNode->packBitsForVariableDataMembers(); m_state.popClassContext(); //restore } //packBitsForClassInstances
void SymbolClassName::calcMaxDepthOfFunctionsForClassInstances() { NodeBlockClass * classNode = getClassBlockNode(); assert(classNode); m_state.pushClassContext(getUlamTypeIdx(), classNode, classNode, false, NULL); classNode->calcMaxDepthOfFunctions(); m_state.popClassContext(); //restore } //calcMaxDepthOfFunctionsForClassInstances
void SymbolClassName::checkCustomArraysOfClassInstances() { NodeBlockClass * classNode = getClassBlockNode(); assert(classNode); m_state.pushClassContext(getUlamTypeIdx(), classNode, classNode, false, NULL); classNode->checkCustomArrayTypeFunctions(); m_state.popClassContext(); //restore } //checkCustomArraysOfClassInstances()
void SymbolClassName::checkAbstractInstanceErrorsForClassInstances() { NodeBlockClass * classNode = getClassBlockNode(); assert(classNode); m_state.pushClassContext(getUlamTypeIdx(), classNode, classNode, false, NULL); classNode->checkAbstractInstanceErrors(); m_state.popClassContext(); //restore return; } //checkAbstractInstanceErrorsForClassInstances
bool SymbolClassName::calcMaxIndexOfVirtualFunctionsForClassInstances() { NodeBlockClass * classNode = getClassBlockNode(); assert(classNode); m_state.pushClassContext(getUlamTypeIdx(), classNode, classNode, false, NULL); classNode->calcMaxIndexOfVirtualFunctions(); m_state.popClassContext(); //restore return (classNode->getVirtualMethodMaxIdx() != UNKNOWNSIZE); } //calcMaxIndexOfVirtualFunctionsForClassInstances
void SymbolTableOfClasses::printForDebugForTableOfClasses(File * fp) { std::map<u32, Symbol *>::iterator it = m_idToSymbolPtr.begin(); while(it != m_idToSymbolPtr.end()) { Symbol * sym = it->second; assert(sym && sym->isClass()); NodeBlockClass * classNode = ((SymbolClass *) sym)->getClassBlockNode(); assert(classNode); m_state.pushClassContext(sym->getUlamTypeIdx(), classNode, classNode, false, NULL); classNode->print(fp); m_state.popClassContext(); //restore it++; } //while } //printForDebugForTableOfClasses
void SymbolClassName::countNavNodesInClassInstances(u32& ncnt, u32& hcnt, u32& nocnt) { assert(!isClassTemplate()); u32 navCounter = ncnt; u32 hzyCounter = hcnt; u32 unsetCounter = nocnt; NodeBlockClass * classNode = getClassBlockNode(); assert(classNode); m_state.pushClassContext(getUlamTypeIdx(), classNode, classNode, false, NULL); classNode->countNavHzyNoutiNodes(ncnt, hcnt, nocnt); if((ncnt - navCounter) > 0) { std::ostringstream msg; msg << navCounter << " data member nodes with erroneous types remain in class '"; msg << m_state.getUlamTypeNameBriefByIndex(getUlamTypeIdx()).c_str(); msg << "'"; MSG(classNode->getNodeLocationAsString().c_str(), msg.str().c_str(), INFO); } if((hcnt - hzyCounter) > 0) { std::ostringstream msg; msg << hzyCounter << " data member nodes with unresolved types remain in class '"; msg << m_state.getUlamTypeNameBriefByIndex(getUlamTypeIdx()).c_str(); msg << "'"; MSG(classNode->getNodeLocationAsString().c_str(), msg.str().c_str(), INFO); } if((nocnt - unsetCounter) > 0) { std::ostringstream msg; msg << unsetCounter << " data member nodes with unset types remain in class '"; msg << m_state.getUlamTypeNameBriefByIndex(getUlamTypeIdx()).c_str(); msg << "'"; MSG(classNode->getNodeLocationAsString().c_str(), msg.str().c_str(), INFO); } SymbolClass::countNavNodesInClassResolver(ncnt, hcnt, nocnt); m_state.popClassContext(); //restore return; } //countNavNodesInClassInstances
void SymbolClassName::checkAndLabelClassFirst() { NodeBlockClass * classNode = getClassBlockNode(); if(!classNode) { std::ostringstream msg; msg << "Check and Label skipped for a class '"; msg << m_state.getUlamTypeNameByIndex(getUlamTypeIdx()).c_str(); msg << "' without a definition (maybe not a class at all)"; MSG(Symbol::getTokPtr(), msg.str().c_str(), ERR); return; } m_state.pushClassContext(getUlamTypeIdx(), classNode, classNode, false, NULL); classNode->checkAndLabelType(); m_state.popClassContext(); //restore } //checkAndLabelClassFirst()
void SymbolClassName::updateLineageOfClass() { NodeBlockClass * classNode = getClassBlockNode(); if(!classNode) { std::ostringstream msg; msg << "LineageUpdate skipped for a class '"; msg << m_state.getUlamTypeNameByIndex(getUlamTypeIdx()).c_str(); msg << "' without a definition (maybe not a class at all)"; MSG(Symbol::getTokPtr(), msg.str().c_str(), ERR); return; } m_state.pushClassContext(getUlamTypeIdx(), classNode, classNode, false, NULL); classNode->updateLineage(0); m_state.popClassContext(); //restore } //updateLineageOfClass
UTI SymbolTableOfClasses::findClassNodeNoForTableOfClasses(NNO n) { std::map<u32, Symbol *>::iterator it = m_idToSymbolPtr.begin(); while(it != m_idToSymbolPtr.end()) { Symbol * sym = it->second; assert(sym->isClass()); UTI cuti = sym->getUlamTypeIdx(); //skip anonymous classes if(!m_state.isAnonymousClass(cuti) && m_state.isASeenClass(cuti)) { NodeBlockClass * classblock = ((SymbolClassName *) sym)->getClassBlockNode(); if(classblock->getNodeNo() == n) return sym->getUlamTypeIdx(); //found it!! } it++; } //while return Nouti; } //findClassNodeNoForTableOfClasses
Node * SymbolClassName::findNodeNoInAClassInstance(UTI instance, NNO n) { assert(getUlamTypeIdx() == instance); Node * foundNode = NULL; NodeBlockClass * classNode = getClassBlockNode(); assert(classNode); m_state.pushClassContext(getUlamTypeIdx(), classNode, classNode, false, NULL); classNode->findNodeNo(n, foundNode); //if not in the tree, ask the resolver if(!foundNode) { SymbolClass::findNodeNoInResolver(n, foundNode); } m_state.popClassContext(); //restore return foundNode; } //findNodeNoInAClassInstance
u32 SymbolClassName::countNavNodesInClassInstances() { assert(!isClassTemplate()); u32 navCounter = 0; NodeBlockClass * classNode = getClassBlockNode(); assert(classNode); m_state.pushClassContext(getUlamTypeIdx(), classNode, classNode, false, NULL); classNode->countNavNodes(navCounter); if(navCounter > 0) { std::ostringstream msg; msg << navCounter << " data member nodes with unresolved types remain in class '"; msg << m_state.getUlamTypeNameBriefByIndex(getUlamTypeIdx()).c_str(); msg << "'"; MSG(classNode->getNodeLocationAsString().c_str(), msg.str().c_str(), WARN); } m_state.popClassContext(); //restore return navCounter; } //countNavNodesInClassInstances
void SymbolTableOfClasses::printPostfixForTableOfClasses(File * fp) { std::map<u32, Symbol *>::iterator it = m_idToSymbolPtr.begin(); while(it != m_idToSymbolPtr.end()) { Symbol * sym = it->second; assert(sym && sym->isClass()); UTI cuti = sym->getUlamTypeIdx(); //skip anonymous classes; skip UrSelf to avoid extensive changes all test answers. //skip Empty to avoid extensive changes all test answers. if(!m_state.isAnonymousClass(cuti) && m_state.isASeenClass(cuti) && !m_state.isUrSelf(cuti) && !m_state.isEmptyElement(cuti)) { NodeBlockClass * classNode = ((SymbolClass *) sym)->getClassBlockNode(); assert(classNode); m_state.pushClassContext(cuti, classNode, classNode, false, NULL); classNode->printPostfix(fp); m_state.popClassContext(); //restore } it++; } //while } //printPostfixForTableOfClasses
// replaces NodeVarDecl:printPostfix to learn the values of Class' storage in center site void SymbolVariableDataMember::printPostfixValuesOfVariableDeclarations(File * fp, s32 slot, u32 startpos, ULAMCLASSTYPE classtype) { UTI vuti = getUlamTypeIdx(); UlamKeyTypeSignature vkey = m_state.getUlamKeyTypeSignatureByIndex(vuti); UlamType * vut = m_state.getUlamTypeByIndex(vuti); ULAMCLASSTYPE vclasstype = vut->getUlamClass(); fp->write(" "); if(vclasstype == UC_NOTACLASS) fp->write(vkey.getUlamKeyTypeSignatureNameAndBitSize(&m_state).c_str()); else fp->write(vut->getUlamTypeNameBrief().c_str()); fp->write(" "); fp->write(m_state.m_pool.getDataAsString(getId()).c_str()); s32 arraysize = m_state.getArraySize(vuti); //scalar has 'size=1'; empty array [0] is still '0'. s32 size = (arraysize > NONARRAYSIZE ? arraysize : 1); //output the arraysize (optional), and open paren if(arraysize > NONARRAYSIZE) { fp->write("["); fp->write_decimal(arraysize); fp->write("]"); } else if(arraysize == UNKNOWNSIZE) { fp->write("[UNKNOWN]"); } fp->write("("); if(vclasstype == UC_QUARK) { //printPostfixValuesForClass: SymbolClass * csym = NULL; if(m_state.alreadyDefinedSymbolClass(vuti, csym)) { NodeBlockClass * classNode = csym->getClassBlockNode(); assert(classNode); SymbolTable * stptr = classNode->getSymbolTablePtr(); //ST of data members u32 newstartpos = startpos + getPosOffset(); s32 len = vut->getBitSize(); for(s32 i = 0; i < size; i++) stptr->printPostfixValuesForTableOfVariableDataMembers(fp, slot, newstartpos + len * i, vclasstype); } else { assert(0); //error! } } else { PACKFIT packFit = m_state.determinePackable(vuti); assert(WritePacked(packFit)); //has to be to fit in an atom/site; char * valstr = new char[size * 8 + MAXBITSPERLONG]; //was 32 if(size > 0) { //simplifying assumption for testing purposes: center site //Coord c0(0,0); //u32 slot = c0.convertCoordToIndex(); //build the string of values (for both scalar and packed array) UlamValue arrayPtr = UlamValue::makePtr(slot, EVENTWINDOW, vuti, packFit, m_state, startpos + getPosOffset(), getId()); UlamValue nextPtr = UlamValue::makeScalarPtr(arrayPtr, m_state); UlamValue atval = m_state.getPtrTarget(nextPtr); s32 len = nextPtr.getPtrLen(); assert(len != UNKNOWNSIZE); if(len <= MAXBITSPERINT) { u32 data = atval.getDataFromAtom(nextPtr, m_state); vut->getDataAsString(data, valstr, 'z'); //'z' -> no preceeding ',' for(s32 i = 1; i < size; i++) { char tmpstr[8]; assert(nextPtr.incrementPtr(m_state)); atval = m_state.getPtrTarget(nextPtr); data = atval.getDataFromAtom(nextPtr, m_state); vut->getDataAsString(data, tmpstr, ','); strcat(valstr,tmpstr); } } else if(len <= MAXBITSPERLONG) { u64 data = atval.getDataLongFromAtom(nextPtr, m_state); vut->getDataLongAsString(data, valstr, 'z'); //'z' -> no preceeding ',' for(s32 i = 1; i < size; i++) { char tmpstr[8]; assert(nextPtr.incrementPtr(m_state)); atval = m_state.getPtrTarget(nextPtr); data = atval.getDataLongFromAtom(nextPtr, m_state); vut->getDataLongAsString(data, tmpstr, ','); strcat(valstr,tmpstr); } } else assert(0); } //end arrays > 0, and scalar else { sprintf(valstr," "); } fp->write(valstr); //results out here! delete [] valstr; } //not a quark fp->write("); "); } //printPostfixValuesOfVariableDeclarations
// replaces NodeVarDecl:printPostfix to learn the values of Class' storage in center site void SymbolVariableDataMember::printPostfixValuesOfVariableDeclarations(File * fp, s32 slot, u32 startpos, ULAMCLASSTYPE classtype) { UTI vuti = getUlamTypeIdx(); UlamKeyTypeSignature vkey = m_state.getUlamKeyTypeSignatureByIndex(vuti); UlamType * vut = m_state.getUlamTypeByIndex(vuti); ULAMCLASSTYPE vclasstype = vut->getUlamClassType(); ULAMTYPE vetyp = vut->getUlamTypeEnum(); fp->write(" "); if(vclasstype == UC_NOTACLASS) fp->write(vkey.getUlamKeyTypeSignatureNameAndBitSize(&m_state).c_str()); else fp->write(vut->getUlamTypeNameBrief().c_str()); fp->write(" "); fp->write(m_state.m_pool.getDataAsString(getId()).c_str()); s32 arraysize = m_state.getArraySize(vuti); //scalar has 'size=1'; empty array [0] is still '0'. s32 size = (arraysize > NONARRAYSIZE ? arraysize : 1); //output the arraysize (optional), and open paren if(arraysize > NONARRAYSIZE) { fp->write("["); fp->write_decimal(arraysize); fp->write("]"); } else if(arraysize == UNKNOWNSIZE) { fp->write("[UNKNOWN]"); } fp->write("("); if(vclasstype == UC_QUARK) { //outputs the data members, not just the lump value (e.g. SWV::printPostfixValue()) UTI scalarquark = m_state.getUlamTypeAsScalar(vuti); //printPostfixValuesForClass: SymbolClass * csym = NULL; AssertBool isDefined = m_state.alreadyDefinedSymbolClass(scalarquark, csym); assert(isDefined); NodeBlockClass * classNode = csym->getClassBlockNode(); assert(classNode); u32 newstartpos = startpos + getPosOffset(); s32 len = vut->getBitSize(); for(s32 i = 0; i < size; i++) classNode->printPostfixDataMembersSymbols(fp, slot, newstartpos + len * i, vclasstype); } else { PACKFIT packFit = m_state.determinePackable(vuti); assert(WritePacked(packFit)); //has to be to fit in an atom/site; char * valstr = new char[size * 8 + MAXBITSPERLONG]; //was 32 if(size > 0) { //build the string of values (for both scalar and packed array) UlamValue arrayPtr = UlamValue::makePtr(slot, EVENTWINDOW, vuti, packFit, m_state, startpos + getPosOffset(), getId()); UlamValue nextPtr = UlamValue::makeScalarPtr(arrayPtr, m_state); UlamValue atval = m_state.getPtrTarget(nextPtr); s32 len = m_state.getBitSize(vuti); if(len == UNKNOWNSIZE) { sprintf(valstr,"unknown"); for(s32 i = 1; i < size; i++) { strcat(valstr,", unknown"); } } else if(len <= MAXBITSPERINT) { u32 data = atval.getDataFromAtom(nextPtr, m_state); vut->getDataAsString(data, valstr, 'z'); //'z' -> no preceeding ',' if(vetyp == Unsigned || vetyp == Unary) strcat(valstr, "u"); for(s32 i = 1; i < size; i++) { char tmpstr[8]; AssertBool isNext = nextPtr.incrementPtr(m_state); assert(isNext); atval = m_state.getPtrTarget(nextPtr); data = atval.getDataFromAtom(nextPtr, m_state); vut->getDataAsString(data, tmpstr, ','); if(vetyp == Unsigned || vetyp == Unary) strcat(tmpstr, "u"); strcat(valstr,tmpstr); } } else if(len <= MAXBITSPERLONG) { u64 data = atval.getDataLongFromAtom(nextPtr, m_state); vut->getDataLongAsString(data, valstr, 'z'); //'z' -> no preceeding ',' if(vetyp == Unsigned || vetyp == Unary) strcat(valstr, "u"); for(s32 i = 1; i < size; i++) { char tmpstr[8]; AssertBool isNext = nextPtr.incrementPtr(m_state); assert(isNext); atval = m_state.getPtrTarget(nextPtr); data = atval.getDataLongFromAtom(nextPtr, m_state); vut->getDataLongAsString(data, tmpstr, ','); if(vetyp == Unsigned || vetyp == Unary) strcat(tmpstr, "u"); strcat(valstr,tmpstr); } } else assert(0); } //end arrays > 0, and scalar else { sprintf(valstr," "); } fp->write(valstr); //results out here! delete [] valstr; } //not a quark fp->write("); "); } //printPostfixValuesOfVariableDeclarations
Node * NodeBinaryOpCompare::buildOperatorOverloadFuncCallNode() { Token identTok; TokenType opTokType = Token::getTokenTypeFromString(getName()); assert(opTokType != TOK_LAST_ONE); Token opTok(opTokType, getNodeLocation(), 0); u32 opolId = Token::getOperatorOverloadFullNameId(opTok, &m_state); if(opolId == 0) { std::ostringstream msg; msg << "Overload for operator <" << getName(); msg << "> is not supported as operand for class: "; msg << m_state.getUlamTypeNameBriefByIndex(m_nodeLeft->getNodeType()).c_str(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); return NULL; } identTok.init(TOK_IDENTIFIER, getNodeLocation(), opolId); //may need to negate the opposite comparison, if this one isn't defined (t41109) UTI luti = m_nodeLeft->getNodeType(); SymbolClass * csym = NULL; AssertBool isDefined = m_state.alreadyDefinedSymbolClass(luti, csym); assert(isDefined); NodeBlockClass * memberClassNode = csym->getClassBlockNode(); assert(memberClassNode); //e.g. forgot the closing brace on quark definition assert(m_state.okUTItoContinue(memberClassNode->getNodeType())); //set up compiler state to use the member class block for symbol searches m_state.pushClassContextUsingMemberClassBlock(memberClassNode); Symbol * fnsymptr = NULL; bool hazyKin = false; //unused bool useInverseOp = false; if(!m_state.isFuncIdInClassScope(opolId, fnsymptr, hazyKin)) { //try inverse! const char * invopname = getInverseOpName(); if(!invopname) return NULL; //built-in error msg opTokType = Token::getTokenTypeFromString(invopname); assert(opTokType != TOK_LAST_ONE); opTok.init(opTokType, getNodeLocation(), 0); opolId = Token::getOperatorOverloadFullNameId(opTok, &m_state); assert(opolId != 0); if(!m_state.isFuncIdInClassScope(opolId, fnsymptr, hazyKin)) { std::ostringstream msg; msg << "Overload for operator <" << getName(); msg << "> and its inverse <" << invopname; msg << "> are not supported as operand for class: "; msg << m_state.getUlamTypeNameBriefByIndex(luti).c_str(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); return NULL; } else //continue with a bang { std::ostringstream msg; msg << "Using overload operator <" << getName(); msg << ">'s negated inverse <" << invopname; msg << "> operator for class: "; msg << m_state.getUlamTypeNameBriefByIndex(luti).c_str(); MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), DEBUG); useInverseOp = true; } } //else continue without a bang //clear up compiler state to no longer use the member class block for symbol searches m_state.popClassContext(); identTok.init(TOK_IDENTIFIER, getNodeLocation(), opolId); //fill in func symbol during type labeling; NodeFunctionCall * fcallNode = new NodeFunctionCall(identTok, NULL, m_state); assert(fcallNode); fcallNode->setNodeLocation(identTok.m_locator); fcallNode->addArgument(m_nodeRight); Node * rnode = fcallNode; if(useInverseOp) { rnode = new NodeUnaryOpBang(fcallNode, m_state); rnode->setNodeLocation(identTok.m_locator); } NodeMemberSelect * mselectNode = new NodeMemberSelect(m_nodeLeft, rnode, m_state); assert(mselectNode); mselectNode->setNodeLocation(identTok.m_locator); //redo check and type labeling done by caller!! return mselectNode; //replace right node with new branch } //buildOperatorOverloadFuncCallNode
UTI NodeMemberSelect::checkAndLabelType() { assert(m_nodeLeft && m_nodeRight); UTI luti = m_nodeLeft->checkAndLabelType(); //side-effect TBOOL lstor = m_nodeLeft->getStoreIntoAble(); if(lstor != TBOOL_TRUE) { //e.g. funcCall is not storeintoable even if its return value is. std::ostringstream msg; msg << "Member selected must be a valid lefthand side: '"; msg << m_nodeLeft->getName(); msg << "' requires a variable; may be a casted function call"; if(lstor == TBOOL_HAZY) { MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT); setNodeType(Hzy); m_state.setGoAgain(); return Hzy; } else { MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); setNodeType(Nav); return Nav; } } //done if(!m_state.isComplete(luti)) { std::ostringstream msg; msg << "Member selected is incomplete class: "; msg << m_state.getUlamTypeNameBriefByIndex(luti).c_str(); msg << ", check and label fails this time around"; if(luti == Nav) { MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); setNodeType(Nav); } else { MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), WAIT); setNodeType(Hzy); m_state.setGoAgain(); //since no error msg } return getNodeType(); } //done UlamType * lut = m_state.getUlamTypeByIndex(luti); ULAMCLASSTYPE classtype = lut->getUlamClassType(); if(((classtype == UC_NOTACLASS) && (lut->getUlamTypeEnum() != Holder)) || !lut->isScalar()) { // must be a scalar 'Class' type, (e.g. error/t3815) // doesn't complete checkandlabel for rhs (e.g. funccall is NULL, no eval) std::ostringstream msg; msg << "Member selected must be a Class, not type: "; msg << m_state.getUlamTypeNameBriefByIndex(luti).c_str(); if(classtype != UC_NOTACLASS) msg << "[" << lut->getArraySize() << "]"; if(m_state.isAtom(luti)) msg << "; suggest using a Conditional-As"; MSG(getNodeLocationAsString().c_str(), msg.str().c_str(), ERR); setNodeType(Nav); return Nav; } //done std::string className = m_state.getUlamTypeNameBriefByIndex(luti); //help me debug SymbolClass * csym = NULL; AssertBool isDefined = m_state.alreadyDefinedSymbolClass(luti, csym); assert(isDefined); NodeBlockClass * memberClassNode = csym->getClassBlockNode(); assert(memberClassNode); //e.g. forgot the closing brace on quark definition assert(m_state.okUTItoContinue(memberClassNode->getNodeType())); //t41010 //set up compiler state to use the member class block for symbol searches m_state.pushClassContextUsingMemberClassBlock(memberClassNode); UTI rightType = m_nodeRight->checkAndLabelType(); //clear up compiler state to no longer use the member class block for symbol searches m_state.popClassContext(); setNodeType(rightType); //set Nav if error (t3513) if(m_state.okUTItoContinue(rightType)) { //based on righthand side Node::setStoreIntoAble(m_nodeRight->getStoreIntoAble()); //base reference-ability on righthand side (t41085) Node::setReferenceAble(m_nodeRight->getReferenceAble()); } return getNodeType(); } //checkAndLabelType