Beispiel #1
0
/// Debug routine to print the given node and its immediate children. The node address is the only mandatory
/// argument; the other arguments are a textual description, and a start index and a node count. The start index
/// tells the subroutine where to start printing (0 means the given node itself, 1 means the first child node,
/// n means the n-th child node. The count gives the number of child nodes which should be printed;
/// 0 means print only the given node, 1 means print only one child node, etc.
void SCoPVisitor::printNode(const NodeAddress &node, std::string descr, unsigned int start, int count) {
	// determine total number of child nodes, and adjust count accordingly
	auto children=node.getChildAddresses();
	if (count<0) count=children.size();

	// if requested (start=0), print the node itself with some debug information
	if (start==0) {
		if (!descr.empty()) descr=" ("+descr+")";
		std::cout << std::endl << node.getNodeType() << descr << ": " << node << std::endl;
		start++;
	}

	// iterate over the requested children to complete the output
	for (unsigned int n=start-1; n<start-1+count; n++)
		std::cout << "\t-" << n << "\t" << children[n].getNodeType() << ": " << *children[n] << std::endl;
}
Beispiel #2
0
CodeLocation CodeLocation::shift(const NodeAddress& outer, const utils::AnnotationKeyPtr& key) const {

	// make some assumptions
	assert_true(outer.hasAnnotation(key));
	assert(any(outer.getAnnotation(key)->getChildNodes(), [&](const NodePtr& cur) { return cur == address.getRootNode(); }));

	// create a copy of this instance
	CodeLocation res = *this;

	// update the annotation path
	res.annotationPath.insert(res.annotationPath.begin(), std::make_pair(key, address));

	// update the address
	res.address = outer;

	// done
	return res;
}
Beispiel #3
0
NodeAddress getRootVariable(NodeAddress var) {
	// search in declaration in siblings
	NodeAddress parent = var.getParentAddress(1);
	return getRootVariable(parent, var);
}
Beispiel #4
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);
}
Beispiel #5
0
	NodeAddress normalize(const NodeAddress& node) {
		return node.switchRoot(normalize(node.getRootNode()));
	}
Beispiel #6
0
/// Visit all the child nodes of the given node. The given node itself is not taken into account.
/// Hence, this subroutine can only be used in the case you want to traverse all children unconditionally. When
/// visiting single child nodes, you cannot use this function to do the work.
void SCoPVisitor::visitChildren(const NodeAddress &node) {
	for (auto child: node->getChildList()) visit(child);
}