RefDNode DCompiler::ByReference(RefDNode nIn) { static RefDNode null = static_cast<RefDNode>(antlr::nullAST); // #ifdef GDL_DEBUG // cout << "ByReference: in:" << endl; // antlr::print_tree pt; // pt.pr_tree(static_cast<antlr::RefAST>( nIn)); // cout << endl; // #endif RefDNode n = nIn; // APRO,++(a=2) is passed like APRO,a // APRO,(((a=2))=3) // forbidden in GDL // Makes IDL segfault: APRO,++(((a=2))=3) int t=n->getType(); // expressions (braces) are ignored do { while( n->getType() == EXPR) n = n->getFirstChild(); t = n->getType(); if( t == DEC || t == INC) // only preinc can be reference { n = n->getFirstChild(); t = n->getType(); } } while( t == DEC || t == INC || t == EXPR); // // expressions (braces) are ignored // while( n->getType() == EXPR) n = n->getFirstChild(); // t=n->getType(); bool assignReplace = false; if( t == ASSIGN_REPLACE) { assignReplace = true; n = n->getFirstChild()->getNextSibling(); t=n->getType(); } // expressions (braces) are ignored while( n->getType() == EXPR) n = n->getFirstChild(); t=n->getType(); // only var, common block var and deref ptr are passed by reference // note: trinary op is REF_CHECK // *** see AssignReplace(...) if( !assignReplace && t != VAR && t != VARPTR && t != DEREF && !GDLTreeParser::IsREF_CHECK(t)) // && t != QUESTION) return null; // #ifdef GDL_DEBUG // cout << "ByReference: out:" << endl; // pt.pr_tree(static_cast<antlr::RefAST>( n)); // cout << endl; // #endif return n; }