static void view_ast(BaseAST* ast, bool number = false, int mark = -1, int indent = 0) { if (!ast) return; if (Expr* expr = toExpr(ast)) { printf("\n"); for (int i = 0; i < indent; i++) printf(" "); printf("("); if (ast->id == mark) printf("***"); if (number) printf("%d ", ast->id); printf("%s", expr->astTagAsString()); if (isBlockStmt(expr)) if (FnSymbol* fn = toFnSymbol(expr->parentSymbol)) if (expr == fn->where) printf(" where"); if (GotoStmt *gs= toGotoStmt(ast)) { printf( " "); view_ast(gs->label, number, mark, indent+1); } if (CallExpr* call = toCallExpr(expr)) if (call->primitive) printf(" %s", call->primitive->name); if (NamedExpr* named = toNamedExpr(expr)) printf(" \"%s\"", named->name); if (toDefExpr(expr)) printf(" "); int64_t i; const char *str; if (get_int(expr, &i)) { printf(" %" PRId64, i); } else if (get_string(expr, &str)) { printf(" \"%s\"", str); } if (SymExpr* sym = toSymExpr(expr)) { printf(" "); view_sym(sym->var, number, mark); } else if (UnresolvedSymExpr* sym = toUnresolvedSymExpr(expr)) { printf(" '%s'", sym->unresolved); } } if (Symbol* sym = toSymbol(ast)) { view_sym(sym, number, mark); } AST_CHILDREN_CALL(ast, view_ast, number, mark, indent+2); if (toExpr(ast)) printf(")"); }
BlockStmt* BlockStmt::copyInner(SymbolMap* map) { BlockStmt* _this = new BlockStmt(); _this->blockTag = blockTag; _this->blockInfo = COPY_INT(blockInfo); _this->useList = COPY_INT(useList); _this->byrefVars = COPY_INT(byrefVars); for_alist(expr, body) { Expr* copy = COPY_INT(expr); _this->insertAtTail(copy); if (DefExpr* def = toDefExpr(copy)) { if (TypeSymbol* ts = toTypeSymbol(def->sym)) { if (EnumType* et = toEnumType(ts->type)) { // ensure we have the size, cast functions, etc. // Lydia NOTE: This relies on making no copies of enum types prior to // buildDefaultFunctions(). The creation must happen here because // otherwise the EnumType will not have the correct symbol, and the // symbol will not be in the tree. buildEnumFunctions(et); } } } }
forv_Vec(DefExpr, def, gDefExprs) { if (toVarSymbol(def->sym)) { // The test for FLAG_TEMP allows compiler-generated (temporary) variables // to be declared without an explicit type or initializer expression. if ((!def->init || def->init->isNoInitExpr()) && !def->exprType && !def->sym->hasFlag(FLAG_TEMP)) if (isBlockStmt(def->parentExpr) && !isArgSymbol(def->parentSymbol)) if (def->parentExpr != rootModule->block && def->parentExpr != stringLiteralModule->block) if (!def->sym->hasFlag(FLAG_INDEX_VAR)) USR_FATAL_CONT(def->sym, "Variable '%s' is not initialized or has no type", def->sym->name); } // // This test checks to see if query domains (e.g., '[?D]') are // used in places other than formal argument type specifiers. // if (!isFnSymbol(def->parentSymbol)) { if (CallExpr* type = toCallExpr(def->exprType)) { if (type->isNamed("chpl__buildArrayRuntimeType")) { if (CallExpr* domainExpr = toCallExpr(type->get(1))) { DefExpr* queryDomain = toDefExpr(domainExpr->get(1)); if (queryDomain) { USR_FATAL_CONT(queryDomain, "Domain query expressions may currently only be used in formal argument types"); } } } } } checkPrivateDecls(def); }
// // Determine the index type for a ParamForLoop. // // This implementation creates a range with low/high values and then // asks for its type. // Type* ParamForLoop::indexType() { SymExpr* lse = lowExprGet(); SymExpr* hse = highExprGet(); CallExpr* range = new CallExpr("chpl_build_bounded_range", lse->copy(), hse->copy()); Type* idxType = 0; insertBefore(range); resolveCall(range); if (FnSymbol* sym = range->isResolved()) { resolveFormals(sym); DefExpr* formal = toDefExpr(sym->formals.get(1)); if (toArgSymbol(formal->sym)->typeExpr) idxType = toArgSymbol(formal->sym)->typeExpr->body.tail->typeInfo(); else idxType = formal->sym->type; range->remove(); } else { INT_FATAL("unresolved range"); } return idxType; }
GenRet BlockStmt::codegen() { GenInfo* info = gGenInfo; FILE* outfile = info->cfile; GenRet ret; codegenStmt(this); if( outfile ) { if (blockInfo) { if (blockInfo->isPrimitive(PRIM_BLOCK_WHILEDO_LOOP)) { std::string hdr = "while (" + codegenValue(blockInfo->get(1)).c + ") "; info->cStatements.push_back(hdr); } else if (blockInfo->isPrimitive(PRIM_BLOCK_DOWHILE_LOOP)) { info->cStatements.push_back("do "); } else if (blockInfo->isPrimitive(PRIM_BLOCK_FOR_LOOP)) { std::string hdr = "for (;" + codegenValue(blockInfo->get(1)).c + ";) "; info->cStatements.push_back(hdr); } else if (blockInfo->isPrimitive(PRIM_BLOCK_XMT_PRAGMA_FORALL_I_IN_N)) { std::string hdr = "_Pragma(\"mta for all streams "; hdr += codegenValue(blockInfo->get(1)).c; hdr += " of "; hdr += codegenValue(blockInfo->get(2)).c; hdr += "\")\n"; info->cStatements.push_back(hdr); } } if (this != getFunction()->body) info->cStatements.push_back("{\n"); if (!(fNoRepositionDefExpr)) { Vec<BaseAST*> asts; collect_top_asts(this, asts); forv_Vec(BaseAST, ast, asts) { if (DefExpr* def = toDefExpr(ast)) { if (def->parentExpr == this) { if (!toTypeSymbol(def->sym)) { if (fGenIDS && isVarSymbol(def->sym)) info->cStatements.push_back("/* " + numToString(def->sym->id) + " */ "); def->sym->codegenDef(); } } } } } body.codegen(""); if (blockInfo && blockInfo->isPrimitive(PRIM_BLOCK_DOWHILE_LOOP)) { std::string ftr = "} while (" + codegenValue(blockInfo->get(1)).c + ");\n"; info->cStatements.push_back(ftr); } else if (this != getFunction()->body) { std::string end = "}"; CondStmt* cond = toCondStmt(parentExpr); if (!cond || !(cond->thenStmt == this && cond->elseStmt)) end += "\n"; info->cStatements.push_back(end); } } else {
void IpeModuleRoot::init() { mState = kResolved; initialize(); for (int i = 1; i <= sHighWater; i++) { DefExpr* expr = toDefExpr(rootModule->block->body.get(i)); INT_ASSERT(expr); if (mEnv->findLocal(expr->sym->name) != NULL) { printf(" Attempt to redefine identifier %s\n", expr->sym->name); INT_ASSERT(false); } else if (TypeSymbol* sym = toTypeSymbol(expr->sym)) { int offset = mEnv->allocateValue(sym->type); VarSymbol* var = new VarSymbol(sym->name, gIpeTypeType); INT_ASSERT(expr->exprType == NULL); INT_ASSERT(expr->init == NULL); var->addFlag(FLAG_CONST); var->locationSet(0, offset); mEnv->varAdd(var); } else if (expr->sym->isImmediate() == true) { VarSymbol* var = toVarSymbol(expr->sym); int offset = mEnv->allocateValue(var->type); var->addFlag(FLAG_CONST); var->locationSet(0, offset); mEnv->varAdd(var); } else { AstDumpToNode logger(stdout, 3); printf("Unexpected expression while initializing RootModule\n"); printf(" "); expr->accept(&logger); printf("\n"); INT_ASSERT(false); } } moduleAdd(this); }
bool Expr::isModuleDefinition() { bool retval = false; #if 1 // MDN 2014/07/02 // Leaving the old definition here until the scope-less BlockStmt // change is stable. if (BlockStmt* block = toBlockStmt(this)) if (block->length() == 1) if (DefExpr* def = toDefExpr(block->body.only())) if (isModuleSymbol(def->sym)) retval = true; #endif if (DefExpr* def = toDefExpr(this)) if (isModuleSymbol(def->sym)) retval = true; return retval; }
// // Removes gotos where the label immediately follows the goto and // unused labels // void removeUnnecessaryGotos(FnSymbol* fn) { std::vector<BaseAST*> asts; std::set<BaseAST*> labels; collect_asts_STL(fn, asts); for_vector(BaseAST, ast, asts) { if (GotoStmt* gotoStmt = toGotoStmt(ast)) { DefExpr* def = toDefExpr(gotoStmt->next); SymExpr* label = toSymExpr(gotoStmt->label); INT_ASSERT(label); if (def && def->sym == label->var) gotoStmt->remove(); else labels.insert(label->var); } } for_vector(BaseAST, ast2, asts) { if (DefExpr* def = toDefExpr(ast2)) if (LabelSymbol* label = toLabelSymbol(def->sym)) if (labels.find(label) == labels.end()) def->remove(); } }
void Expr::replace(Expr* new_ast) { if (new_ast->parentSymbol || new_ast->parentExpr) INT_FATAL(new_ast, "Argument is already in AST in Expr::replace"); if (new_ast->list) INT_FATAL(new_ast, "Argument is in a list in Expr::replace"); if (list) { new_ast->next = next; new_ast->prev = prev; new_ast->list = list; if (next) next->prev = new_ast; else list->tail = new_ast; if (prev) prev->next = new_ast; else list->head = new_ast; next = NULL; prev = NULL; list = NULL; } else { callReplaceChild(this, new_ast); } Symbol* myParentSymbol = parentSymbol; Expr* myParentExpr = parentExpr; remove_help(this, 'p'); insert_help(new_ast, myParentExpr, myParentSymbol); // Update the _this field in a FnSymbol if necessary. if (DefExpr* def = toDefExpr(this)) if (ArgSymbol* arg = toArgSymbol(def->sym)) if (FnSymbol* fn = toFnSymbol(myParentSymbol)) if (fn->_this == arg) fn->_this = toDefExpr(new_ast)->sym; }
void FnSymbol::verify() { Symbol::verify(); if (astTag != E_FnSymbol) { INT_FATAL(this, "Bad FnSymbol::astTag"); } if (_this && _this->defPoint->parentSymbol != this) INT_FATAL(this, "Each method must contain a 'this' declaration."); if (normalized) { CallExpr* last = toCallExpr(body->body.last()); if (last == NULL || last->isPrimitive(PRIM_RETURN) == false) { INT_FATAL(this, "Last statement in normalized function is not a return"); } } if (formals.parent != this) { INT_FATAL(this, "Bad AList::parent in FnSymbol"); } if (where && where->parentSymbol != this) { INT_FATAL(this, "Bad FnSymbol::where::parentSymbol"); } if (retExprType && retExprType->parentSymbol != this) { INT_FATAL(this, "Bad FnSymbol::retExprType::parentSymbol"); } if (body && body->parentSymbol != this) { INT_FATAL(this, "Bad FnSymbol::body::parentSymbol"); } for_alist(fExpr, formals) { DefExpr* argDef = toDefExpr(fExpr); INT_ASSERT(argDef); INT_ASSERT(isArgSymbol(argDef->sym)); }
GenRet GotoStmt::codegen() { GenInfo* info = gGenInfo; FILE* outfile = info->cfile; GenRet ret; codegenStmt(this); if( outfile ) { info->cStatements.push_back("goto " + label->codegen().c + ";\n"); } else { #ifdef HAVE_LLVM llvm::Function *func = info->builder->GetInsertBlock()->getParent(); const char *cname; if(isDefExpr(label)) { cname = toDefExpr(label)->sym->cname; } else { cname = toSymExpr(label)->symbol()->cname; } llvm::BasicBlock *blockLabel; if(!(blockLabel = info->lvt->getBlock(cname))) { blockLabel = llvm::BasicBlock::Create(info->module->getContext(), cname); info->lvt->addBlock(cname, blockLabel); } info->builder->CreateBr(blockLabel); getFunction()->codegenUniqueNum++; llvm::BasicBlock *afterGoto = llvm::BasicBlock::Create( info->module->getContext(), FNAME("afterGoto")); func->getBasicBlockList().push_back(afterGoto); info->builder->SetInsertPoint(afterGoto); #endif } return ret; }
static void list_ast(BaseAST* ast, BaseAST* parentAst = NULL, int indent = 0) { bool do_list_line = false; bool is_C_loop = false; const char* block_explain = NULL; if (Expr* expr = toExpr(ast)) { do_list_line = !parentAst || list_line(expr, parentAst); if (do_list_line) { printf("%-7d ", expr->id); for (int i = 0; i < indent; i++) printf(" "); } if (GotoStmt* e = toGotoStmt(ast)) { printf("goto "); if (SymExpr* label = toSymExpr(e->label)) { if (label->var != gNil) { list_ast(e->label, ast, indent+1); } } else { list_ast(e->label, ast, indent+1); } } else if (toBlockStmt(ast)) { block_explain = block_explanation(ast, parentAst); printf("%s{\n", block_explain); } else if (toCondStmt(ast)) { printf("if "); } else if (CallExpr* e = toCallExpr(expr)) { if (e->isPrimitive(PRIM_BLOCK_C_FOR_LOOP)) is_C_loop = true; if (e->primitive) printf("%s( ", e->primitive->name); else printf("call( "); } else if (NamedExpr* e = toNamedExpr(expr)) { printf("%s = ", e->name); } else if (toDefExpr(expr)) { printf("def "); } else if (SymExpr* e = toSymExpr(expr)) { list_sym(e->var, false); } else if (UnresolvedSymExpr* e = toUnresolvedSymExpr(expr)) { printf("%s ", e->unresolved); } } if (Symbol* sym = toSymbol(ast)) list_sym(sym); bool early_newline = toFnSymbol(ast) || toModuleSymbol(ast); if (early_newline || is_C_loop) printf("\n"); int new_indent = indent; if (isExpr(ast)) if (do_list_line) new_indent = indent+2; AST_CHILDREN_CALL(ast, list_ast, ast, new_indent); if (Expr* expr = toExpr(ast)) { CallExpr* parent_C_loop = NULL; if (CallExpr* call = toCallExpr(parentAst)) if (call->isPrimitive(PRIM_BLOCK_C_FOR_LOOP)) parent_C_loop = call; if (toCallExpr(expr)) { printf(") "); } if (toBlockStmt(ast)) { printf("%-7d ", expr->id); if (*block_explain) indent -= 2; for (int i = 0; i < indent; i++) printf(" "); if ((parent_C_loop && parent_C_loop->get(3) == expr) || *block_explain) printf("} "); else printf("}\n"); } else if (CondStmt* cond = toCondStmt(parentAst)) { if (cond->condExpr == expr) printf("\n"); } else if (!toCondStmt(expr) && do_list_line) { DefExpr* def = toDefExpr(expr); if (!(def && early_newline)) if (!parent_C_loop) printf("\n"); } } }
// Returns max local frame space to evaluate this expr int locationExpr(Expr* expr, IpeEnv* env) { int retval = 0; if (DefExpr* defExpr = toDefExpr(expr)) { VarSymbol* var = toVarSymbol(defExpr->sym); int delta = 8; // NOAKES Size of every type is currently 8 INT_ASSERT(var); env->locationSet(var); retval = delta; } else if (isCallExpr(expr) == true) retval = 0; else if (CondStmt* stmt = toCondStmt(expr)) { if (stmt->elseStmt == NULL) { retval = locationExpr(stmt->thenStmt, env); } else { int thenSize = locationExpr(stmt->thenStmt, env); int elseSize = locationExpr(stmt->elseStmt, env); retval = (thenSize > elseSize) ? thenSize : elseSize; } } else if (WhileDoStmt* stmt = toWhileDoStmt(expr)) { Expr* body = stmt->body.get(1); INT_ASSERT(stmt->body.length == 1); INT_ASSERT(isBlockStmt(body)); retval = locationExpr(body, env); } else if (BlockStmt* stmt = toBlockStmt(expr)) { IpeBlockStmt* ipeStmt = (IpeBlockStmt*) stmt; int maxFrame = 0; IpeEnv env(ipeStmt->scopeGet()); for (int i = 1; i <= ipeStmt->body.length; i++) { int localSize = locationExpr(ipeStmt->body.get(i), &env); if (localSize > maxFrame) maxFrame = localSize; } retval = maxFrame; } else { AstDumpToNode logger(stdout, 3); printf(" locationExpr(Expr*, IpeEnv* env) unsupported\n"); printf(" "); expr->accept(&logger); printf("\n\n"); env->describe(3); printf("\n\n"); INT_ASSERT(false); } return retval; }
static void list_ast(BaseAST* ast, BaseAST* parentAst = NULL, int indent = 0) { bool do_list_line = false; bool is_C_loop = false; const char* block_explain = NULL; if (Expr* expr = toExpr(ast)) { if (ForallStmt* pfs = toForallStmt(parentAst)) { if (expr == pfs->fRecIterIRdef) { printf("fRecIterIRdef"); } else if (expr == pfs->loopBody()) { if (pfs->numShadowVars() == 0) print_on_its_own_line(indent, "with() do\n"); else print_on_its_own_line(indent, "do\n", false); indent -= 2; } } do_list_line = !parentAst || list_line(expr, parentAst); if (do_list_line) { printf("%-7d ", expr->id); print_indent(indent); } if (const char* expl = forall_explanation_start(ast, parentAst)) printf("%s", expl); if (GotoStmt* e = toGotoStmt(ast)) { printf("goto "); if (SymExpr* label = toSymExpr(e->label)) { if (label->symbol() != gNil) { list_ast(e->label, ast, indent+1); } } else { list_ast(e->label, ast, indent+1); } } else if (toBlockStmt(ast)) { block_explain = block_explanation(ast, parentAst); const char* block_kind = ast->astTagAsString(); if (!strcmp(block_kind, "BlockStmt")) block_kind = ""; printf("%s{%s\n", block_explain, block_kind); } else if (toCondStmt(ast)) { printf("if "); } else if (toIfExpr(ast)) { printf("IfExpr "); } else if (toForallStmt(ast)) { printf("forall\n"); } else if (CallExpr* e = toCallExpr(expr)) { if (e->isPrimitive(PRIM_BLOCK_C_FOR_LOOP)) is_C_loop = true; if (e->primitive) printf("%s( ", e->primitive->name); else printf("call( "); } else if (ForallExpr* e = toForallExpr(expr)) { if (e->zippered) printf("zip "); printf("forall( "); } else if (NamedExpr* e = toNamedExpr(expr)) { printf("%s = ", e->name); } else if (toDefExpr(expr)) { Symbol* sym = toDefExpr(expr)->sym; if (sym->type != NULL) { printf("def %s ", sym->qualType().qualStr()); } else { printf("def "); } } else if (SymExpr* e = toSymExpr(expr)) { list_sym(e->symbol(), false); } else if (UnresolvedSymExpr* e = toUnresolvedSymExpr(expr)) { printf("%s ", e->unresolved); } else if (isUseStmt(expr)) { printf("use "); } } if (Symbol* sym = toSymbol(ast)) list_sym(sym); bool early_newline = toFnSymbol(ast) || toModuleSymbol(ast); if (early_newline || is_C_loop) printf("\n"); int new_indent = indent; if (isExpr(ast)) if (do_list_line) new_indent = indent+2; AST_CHILDREN_CALL(ast, list_ast, ast, new_indent); if (Expr* expr = toExpr(ast)) { CallExpr* parent_C_loop = NULL; if (CallExpr* call = toCallExpr(parentAst)) if (call->isPrimitive(PRIM_BLOCK_C_FOR_LOOP)) parent_C_loop = call; if (toCallExpr(expr)) { printf(") "); } if (toBlockStmt(ast)) { printf("%-7d ", expr->id); if (*block_explain) indent -= 2; print_indent(indent); if ((parent_C_loop && parent_C_loop->get(3) == expr) || *block_explain) printf("} "); else if (isDeferStmt(parentAst)) printf("}"); // newline is coming else printf("}\n"); if (isForallLoopBody(expr) && parentAst != NULL) { print_indent(indent); printf(" end forall %d", parentAst->id); } } else if (ForallExpr* e = toForallExpr(expr)) { if (e->cond) printf(") "); else printf("} "); } else if (UseStmt* use = toUseStmt(expr)) { if (!use->isPlainUse()) { if (use->hasExceptList()) { printf("except "); } else { printf("only "); } bool first = true; for_vector(const char, str, use->named) { if (first) { first = false; } else { printf(", "); } printf("%s", str); } for (std::map<const char*, const char*>::iterator it = use->renamed.begin(); it != use->renamed.end(); ++it) { if (first) { first = false; } else { printf(", "); } printf("%s as %s", it->second, it->first); } printf("\n"); } } else if (CondStmt* cond = toCondStmt(parentAst)) {
void collectDefExprsSTL(BaseAST* ast, std::vector<DefExpr*>& defExprs) { AST_CHILDREN_CALL(ast, collectDefExprsSTL, defExprs); if (DefExpr* defExpr = toDefExpr(ast)) defExprs.push_back(defExpr); }
void collectDefExprs(BaseAST* ast, Vec<DefExpr*>& defExprs) { AST_CHILDREN_CALL(ast, collectDefExprs, defExprs); if (DefExpr* defExpr = toDefExpr(ast)) defExprs.add(defExpr); }
// returns null if this is a catch-all DefExpr* CatchStmt::expr() const { return toDefExpr(_body->body.first()); }