double ArithmeticOperation::getValue() throw (std::invalid_argument) { MathematicOperable* left = leftVariable.get(); MathematicOperable* right = rightVariable.get(); boost::function<double(double, double)> op = getFunctionType(this->op); return (op(left->getValue(), right->getValue())); }
void SplitTree::build( FunctionDef* inFunctionDef, const std::vector<SplitNode*>& inArguments ) { // TIM: hack to make temporaries have a shared position stream _outputPositionInterpolant = new InputInterpolantSplitNode( -1, 0, kSplitBasicType_Float2 ); FunctionType* functionType = getFunctionType( inFunctionDef ); SplitTreeBuilder builder( *this ); // std::cerr << "function args: " << functionType->nArgs << " args passed: " << inArguments.size(); assert( functionType->nArgs == inArguments.size() ); unsigned int i; for( i = 0; i < functionType->nArgs; i++ ) { Decl* argumentDecl = functionType->args[i]; builder.addArgument( argumentDecl, i, inArguments[i] ); } Statement* statement = inFunctionDef->head; while( statement ) { statement->buildSplitTree( builder ); statement = statement->next; } _resultValue = builder.getResultValue(); // we were called with arguments // thus we don't deal with creating // output nodes, or with building // the dominator tree... }
bool BooleanComparison::conditionMet() { bool leftValue = left.get()->conditionMet(); bool rightValue = right.get()->conditionMet(); boost::function<bool(bool, bool)> fun = getFunctionType(op); bool vuelta = fun(leftValue, rightValue); return negation == true ? !vuelta : vuelta; }
void SplitTree::build( FunctionDef* inFunctionDef ) { // TIM: hack to make temporaries have a shared position stream _outputPositionInterpolant = new InputInterpolantSplitNode( -1, 0, kSplitBasicType_Float2 ); FunctionType* functionType = getFunctionType( inFunctionDef ); Statement* headStatement = inFunctionDef->head; SplitTreeBuilder builder( *this ); unsigned int i; for( i = 0; i < functionType->nArgs; i++ ) { Decl* argumentDecl = functionType->args[i]; builder.addArgument( argumentDecl, i ); } Statement* statement = headStatement; while( statement ) { statement->buildSplitTree( builder ); statement = statement->next; } _pseudoRoot = new SplitRootNode(); _resultValue = builder.getResultValue(); for( i = 0; i < functionType->nArgs; i++ ) { Decl* argumentDecl = functionType->args[i]; Type* argumentType = argumentDecl->form; std::string name = argumentDecl->name->name; if( (argumentType->getQualifiers() & TQ_Out) != 0 ) { SplitNode* outputValue = builder.findVariable( name )->getValueNode(); _pseudoRoot->addChild( outputValue ); _outputList.push_back( outputValue ); _outputArgumentIndices.push_back( (i+1) ); } } if( _resultValue ) { _pseudoRoot->addChild( _resultValue ); _outputList.push_back( _resultValue ); _outputArgumentIndices.push_back( 0 ); } buildDominatorTree(); // std::cerr << "done" << std::endl; }
QString Repository::Git::GitFunction::getFunctionTypeAsString() { // zoberie typ funkcie a vrati ho ako QString switch ( getFunctionType() ) { case Repository::Git::GitFunctionType::GLOBALFUNCTION: return "globalFunction"; case Repository::Git::GitFunctionType::LOCALFUNCTION: return "function"; default: return "Not set"; } }
bool addOpaqueStruct(Units *units, const char *name, Node *top, int linkage) { Context *ctx = units->top()->ctx; llvm::StructType *llvm_st = llvm::StructType::create(llvm::getGlobalContext(), "created_opaque_type"); std::string symbol; ctx->ns()->nameToSymbol(name, &symbol); std::string llvm_st_name; llvm_st_name.append("struct_"); llvm_st_name.append(symbol); llvm_st->setName(llvm_st_name.c_str()); Struct *st = new Struct(); st->type = llvm_st; st->is_opaque = true; st->linkage = linkage; st->internal_name.append(llvm_st_name.c_str()); st->once_tag = units->top()->once_tag; if (!ctx->ns()->addStruct(name, st)) { /* If the struct already exists, this is not an error. */ if (!ctx->getStruct(name)) { Error *e = new Error(UnableToParseForm, nullNode()); ctx->er->addError(e); return false; } } /* If a struct is not used in a module, it is not included when * the module is serialised. Add an intern function declaration * that takes no arguments and returns a value of the type of this * struct, so as to ensure the struct will always be included when * serialising. */ char buf[16]; sprintf(buf, "__rs%d", ++retain_struct_index); assert(!units->top()->module->getFunction(buf)); std::vector<llvm::Type*> args; llvm::FunctionType *ft = getFunctionType(llvm_st, args, false); units->top()->module->getOrInsertFunction(buf, ft); return true; }
void addVarargsFunctions(Unit *unit) { llvm::Module *mod = unit->module; Context *ctx = unit->ctx; Type *type_pchar = ctx->tr->type_pchar; std::vector<llvm::Type*> va_start_args; va_start_args.push_back(ctx->toLLVMType(type_pchar, NULL, false)); llvm::FunctionType *va_start_ft = getFunctionType( ctx->toLLVMType(ctx->tr->type_void, NULL, true), va_start_args, false ); llvm::Function *va_start_fn = llvm::cast<llvm::Function>( mod->getOrInsertFunction( "llvm.va_start", va_start_ft ) ); va_start_fn->setCallingConv(llvm::CallingConv::C); llvm::Function *va_end_fn = llvm::cast<llvm::Function>( mod->getOrInsertFunction( "llvm.va_end", va_start_ft ) ); va_end_fn->setCallingConv(llvm::CallingConv::C); return; }
void checkTypes(Node* ast, Table *main){ if(ast->n_type == NODE_GREATER || ast->n_type == NODE_LESS || ast->n_type == NODE_GREATEREQUAL || ast->n_type == NODE_LESSEQUAL ){ if(ast->n1->type != TYPE_INT || ast->n2->type != TYPE_INT){ operatorError2Types(ast->n_type,ast->n1->type,ast->n2->type); } ast->type = TYPE_BOOL; } else if(ast->n_type == NODE_PLUS || ast->n_type == NODE_MINUS || ast->n_type == NODE_DIV || ast->n_type == NODE_MUL || ast->n_type == NODE_MOD){ if(ast->n1->type != TYPE_INT || ast->n2->type != TYPE_INT){ operatorError2Types(ast->n_type,ast->n1->type,ast->n2->type); } ast->type = TYPE_INT; } else if(ast->n_type == NODE_EQUAL || ast->n_type == NODE_DIFFERENT){ if(ast->n1->type != ast->n2->type){ operatorError2Types(ast->n_type,ast->n1->type,ast->n2->type); } ast->type = TYPE_BOOL; } else if(ast->n_type == NODE_AND || ast->n_type == NODE_OR){ if(ast->n1->type != TYPE_BOOL || ast->n2->type != TYPE_BOOL){ operatorError2Types(ast->n_type,ast->n1->type,ast->n2->type); } ast->type = TYPE_BOOL; } else if(ast->n_type == NODE_LOADARRAY ){ if(ast->n2->type != TYPE_INT || (ast->n1->type != TYPE_BOOL_ARRAY && ast->n1->type != TYPE_INT_ARRAY)){ operatorError2Types(ast->n_type,ast->n1->type,ast->n2->type); } if(ast->n1->type == TYPE_INT_ARRAY) ast->type = TYPE_INT; else if(ast->n1->type == TYPE_BOOL_ARRAY) ast->type = TYPE_BOOL; else { ast->type = ast->n1->type; } } else if( ast->n_type == NODE_NEWINT || ast->n_type == NODE_NEWBOOL ){ assert(ast->n1!=NULL); if(ast->n1->type != TYPE_INT){ operatorError1Types(ast->n_type,ast->n1->type); } if(ast->n_type == NODE_NEWINT) ast->type = TYPE_INT_ARRAY; else ast->type = TYPE_BOOL_ARRAY; } else if( ast->n_type == NODE_LENGTH){ if((ast->n1->type != TYPE_BOOL_ARRAY && ast->n1->type != TYPE_INT_ARRAY && ast->n1->type != TYPE_STRING_ARRAY)){ operatorError1Types(ast->n_type,ast->n1->type); } ast->type = TYPE_INT; } else if( ast->n_type == NODE_UNARYPLUS || ast->n_type == NODE_UNARYMINUS){ if((ast->n1->type != TYPE_INT)){ operatorError1Types(ast->n_type,ast->n1->type); } ast->type = TYPE_INT; } else if(ast->n_type == NODE_NOT){ if((ast->n1->type != TYPE_BOOL)){ operatorError1Types(ast->n_type,ast->n1->type); } ast->type = TYPE_BOOL; } else if( ast->n_type == NODE_PARSEARGS){ if((ast->n1->type != TYPE_STRING_ARRAY || ast->n2->type != TYPE_INT)){ operatorError2Types(ast->n_type,ast->n1->type,ast->n2->type); } ast->type = TYPE_INT; } else if (ast->n_type == NODE_CALL){ int i = 0; Type astType, tableType; char* id = ast->id->id; Table* aux = getMethodTable(main, id); TableNode* table; table = aux->table->next; ast->type = aux->table->type; ast = ast->n1; while(ast != NULL || table != NULL){ astType = TYPE_VOID; tableType = TYPE_VOID; if(ast != NULL) { astType = ast->type; ast = ast->next; } if(table!=NULL){ //if is a param if(table->isParam == 1) { tableType = table->type; table = table->next; }else{ table = NULL; } } if(astType != tableType){ getErrorCall(i,id, astType, tableType); } i++; } } //Statements else if( ast->n_type == NODE_IFELSE || ast->n_type == NODE_WHILE){ if((ast->n1->type != TYPE_BOOL)){ statementError(ast->n_type,ast->n1->type,TYPE_BOOL); } } else if( ast->n_type == NODE_PRINT){ if((ast->n1->type != TYPE_BOOL && ast->n1->type != TYPE_INT)){ //printf("SOMETHING\n"); statementError1oranother(ast->n_type,ast->n1->type,TYPE_BOOL,TYPE_INT); } ast->type = TYPE_INT; }else if(ast->n_type == NODE_COMPOUNDSTAT){ ast->type = ast->n1->type; } else if(ast->n_type == NODE_STORE || ast->n_type == NODE_STOREARRAY){ ast->type = ast->n1->type; //if has index (se é STORE ARRAY) if(ast->n2!=NULL){ if(ast->n2->type != TYPE_INT || (ast->n1->type != TYPE_BOOL_ARRAY && ast->n1->type != TYPE_INT_ARRAY)){ operatorError2Types(NODE_LOADARRAY,ast->n1->type,ast->n2->type); } if(ast->n1->type == TYPE_INT_ARRAY) ast->type = TYPE_INT; else if(ast->n1->type == TYPE_BOOL_ARRAY) ast->type = TYPE_BOOL; } //se o id é igual à expressao if(ast->type != ast->n3->type){ if(ast->n_type == NODE_STORE) assignmentError(ast->n1->value,ast->n3->type,ast->n1->type); else assignmentErrorArray(ast->n1->value,ast->n3->type,ast->n1->type); } ast->type = ast->n1->type; } else if( ast->n_type == NODE_RETURN){ if(ast->n1!=NULL){ if((ast->n1->type != getFunctionType())){ statementError(ast->n_type,ast->n1->type,getFunctionType()); } }else if(getFunctionType()!=TYPE_VOID){ statementError(ast->n_type,TYPE_VOID,getFunctionType()); } } }
res[ext.getInitStaticLazy()] = OP_CONVERTER({ // we have to build a new function for this init call containing a static variable // // A* initXY(lazy) { // static A a = lazy(); // return &a; // } // // ... and since the construction of a function and all its dependencies is anoying // in the C-AST we create a new IR function including an artificial construct // InitStatic that only covers the magic part ... auto fun = call->getFunctionExpr().as<core::LambdaExprPtr>(); auto retType = fun->getFunctionType()->getReturnType(); auto& mgr = NODE_MANAGER; auto& ext = mgr.getLangExtension<StaticVarBackendExtension>(); core::IRBuilder builder(mgr); // special case for static variables not depending on free variables and is a single static init marker // TODO: if this ever causes a problem that only closed init values may be used fix it here if (!core::analysis::hasFreeVariables(ARG(1)) && ARG(0)->hasAttachedValue<SingleStaticInitMarker>()) { // use a constant initialization by inlining the bind auto value = core::transform::evalLazy(mgr, ARG(1)); auto init = builder.callExpr(ext.getInitStaticConst(), value, call[0]); auto lambda = builder.lambdaExpr(builder.refType(value->getType()), init, core::VariableList()); // this function call is equivalent to a call to the new artifical lambda