예제 #1
0
NodeAddress getRootVariable(NodeAddress var) {
	// search in declaration in siblings
	NodeAddress parent = var.getParentAddress(1);
	return getRootVariable(parent, var);
}
예제 #2
0
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);
}