/* * Builds a ref.deref call around an expression if the it is of ref-type */ core::ExpressionPtr tryDeref(const core::ExpressionPtr& expr) { NodeManager& mgr = expr.getNodeManager(); IRBuilder builder(mgr); const lang::BasicGenerator& gen = expr->getNodeManager().getLangBasic(); // core::ExpressionPtr retExpr = expr; if (core::RefTypePtr&& refTy = expr->getType().isa<core::RefTypePtr>()) { return builder.callExpr(refTy->getElementType(), gen.getRefDeref(), expr); } return expr; }
/* * Builds a ref.deref call around an expression if the it is of type ref<ref<'a>> */ core::ExpressionPtr removeDoubleRef(const core::ExpressionPtr& expr){ if (core::RefTypePtr&& refTy = expr->getType().isa<core::RefTypePtr>()) { // on non array types remove also a single ref if(refTy->getElementType()->getNodeType() == core::NT_RefType || refTy->toString().find("array") == string::npos) { core::NodeManager& mgr = expr->getNodeManager(); const core::IRBuilder& builder(mgr); const lang::BasicGenerator& gen = builder.getLangBasic(); return builder.callExpr(refTy->getElementType(), gen.getRefDeref(), expr); } } return expr; }
/* * takes the expression passed to size (in bytes) and tries to extract the size in number of elements as well as the type to be used */ bool extractSizeFromSizeof(const core::ExpressionPtr& arg, core::ExpressionPtr& size, core::TypePtr& type, bool foundMul) { // get rid of casts NodePtr uncasted = arg; while (uncasted->getNodeType() == core::NT_CastExpr) { uncasted = uncasted.as<CastExprPtr>()->getSubExpression(); } if (const CallExprPtr call = uncasted.isa<CallExprPtr>()) { // check if there is a multiplication if(call->getFunctionExpr()->toString().find(".mul") != string::npos && call->getArguments().size() == 2) { IRBuilder builder(arg->getNodeManager()); // recursively look into arguments of multiplication if(extractSizeFromSizeof(call->getArgument(0), size, type, true)) { if(size) size = builder.callExpr(call->getType(), call->getFunctionExpr(), size, call->getArgument(1)); else size = call->getArgument(1); return true; } if(extractSizeFromSizeof(call->getArgument(1), size, type, true)){ if(size) size = builder.callExpr(call->getType(), call->getFunctionExpr(), call->getArgument(0), size); else size = call->getArgument(0); return true; } } // check if we reached a sizeof call if (call->toString().substr(0, 6).find("sizeof") != string::npos) { // extract the type to be allocated type = call->getArgument(0)->getType().isa<GenericTypePtr>()->getTypeParameter(0); assert(type && "Type could not be extracted!"); if(!foundMul){ // no multiplication, just sizeof alone is passed as argument -> only one element IRBuilder builder(arg->getNodeManager()); size = builder.literal(arg->getNodeManager().getLangBasic().getUInt8(), "1"); return true; } return true; } } return false; }
core::ExpressionPtr getVarOutOfCrazyInspireConstruct(const core::ExpressionPtr& arg) { core::NodeManager& mgr = arg->getNodeManager(); core::IRBuilder builder(mgr); const core::lang::BasicGenerator& gen = mgr.getLangBasic(); // remove stuff added by (void*)& core::CallExprPtr stripped = arg.isa<core::CallExprPtr>(); if (!stripped) { return arg; } auto funExpr = stripped->getFunctionExpr(); if(builder.getNodeManager().getLangBasic().isScalarToArray(funExpr) || builder.getNodeManager().getLangBasic().isRefDeref(funExpr) || gen.isRefReinterpret(funExpr)) { return getVarOutOfCrazyInspireConstruct(stripped->getArgument(0)); } return arg; }
void replaceVars(core::ExpressionPtr& expr, core::NodeMap map) { if(!expr) { return; } core::NodeManager& mgr = expr->getNodeManager(); expr = core::transform::replaceAll(mgr, expr, map, core::transform::globalReplacement).as<core::ExpressionPtr>(); }