NodeAddress getRootVariable(NodeAddress var) { // search in declaration in siblings NodeAddress parent = var.getParentAddress(1); return getRootVariable(parent, var); }
NodeAddress getRootVariable(NodeAddress scope, NodeAddress var) { // if the variable is a literal, its a global variable and should therefore be the root if(var.isa<LiteralAddress>()) { //std::cout << "found literal " << *var << std::endl; return var; } // search in declaration in siblings NodeManager& mgr = var.getNodeManager(); icp::TreePattern localOrGlobalVar = pirp::variable() | pirp::literal(pirp::refType(icp::any), icp::any); icp::TreePattern valueCopy = icp::var("val", pirp::variable()) | pirp::callExpr(mgr.getLangBasic().getRefDeref(), icp::var("val", pirp::variable())) | pirp::callExpr(mgr.getLangBasic().getRefNew(), icp::var("val", pirp::variable())) | pirp::callExpr(mgr.getLangBasic().getRefVar(), icp::var("val", pirp::variable())); // icp::TreePattern valueCopyCast = valueCopy | pirp::castExpr(icp::any, valueCopy); // icp::TreePattern assign = pirp::callExpr((mgr.getLangBasic().getRefAssign()), // single(icp::any)); // icp::var("lhs", pirp::variable()) << valueCopyCast); //std::cout << "var: " << *var << std::endl; //std::cout << "\nscope: " << (scope.getChildAddresses().size()) << std::endl; vector<NodeAddress> childAddresses = scope.getChildAddresses(); for(auto I = childAddresses.rbegin(); I != childAddresses.rend(); ++I) { NodeAddress child = *I; //std::cout << "\tTolles I " << child << std::endl; /* will be implplemented when a propper testcase can be found if(CallExprAddress call = dynamic_address_cast<const CallExpr>(child)) { // if there is an assignment, continue with the variable found at the right hand side if(AddressMatchOpt assignment = assign.matchAddress(call)){ std::cout << "assigning " << printer::PrettyPrinter(assignment->getVarBinding("val").getValue()) << std::endl; std::cout << " to " << printer::PrettyPrinter(assignment->getVarBinding("lhs").getValue()) << std::endl; if(assignment->getVarBinding("lhs").getValue() == var) { return getRootVariable(scope, assignment->getVarBinding("val").getValue()); } } } */ if(child.getDepth() > 4) { if(LambdaAddress lambda = child.isa<LambdaAddress>()) { //std::cout << "Lambda: " << lambda << "\n var " << var << std::endl; // if var is a parameter, continue search for declaration of corresponding argument in outer scope // for(int i = 1; i <= 4; ++i) // std::cout << "\nlp: " << utils::whatIs(lambda.getParentNode(i)) << std::endl; CallExprAddress call = lambda.getParentAddress(4).as<CallExprAddress>(); NodeAddress nextScope, nextVar; for_range(make_paired_range(call->getArguments(), lambda->getParameters()->getElements()), [&](const std::pair<const ExpressionAddress, const VariableAddress>& pair) { if(*var == *pair.second) { nextScope = call.getParentAddress(1); nextVar = tryRemoveDeref(pair.first); return; } }); return getRootVariable(nextScope, nextVar); } } if(DeclarationStmtAddress decl = child.isa<DeclarationStmtAddress>()) { if(*(decl->getVariable()) == *var) { // check if init expression is another variable if(icp::AddressMatchOpt valueInit = valueCopy.matchAddress(decl->getInitialization())) { // if so, continue walk with other variable return getRootVariable(scope, valueInit->getVarBinding("val").getValue()); } //std::cout << "found decl of " << *var << std::endl; // if init is no other varable, the root is found return decl->getVariable(); } } if(CallExprAddress call = var.isa<CallExprAddress>()) { //std::cout << "calling " << *call << std::endl; return getRootVariable(scope, extractVariable(call->getArgument(0))); // crossing my fingers that that will work ;) } } //compound expressions may not open a new scope, therefore declaration can be in the parent return getRootVariable(scope.getParentAddress(), var); }