// Is 'sym' a non-const variable (including formals) defined outside of 'fn'? // This is a modification of isOuterVar() from flattenFunctions.cpp. // static bool isOuterVar(Symbol* sym, FnSymbol* fn) { Symbol* symParent = sym->defPoint->parentSymbol; if (symParent == fn || // no need to search sym->isParameter() || // includes isImmediate() sym->hasFlag(FLAG_TEMP) || // exclude these // Consts need no special semantics for begin/cobegin/coforall/on. // Implementation-wise, it is uniform with consts in nested functions. sym->hasFlag(FLAG_CONST) || // NB 'type' formals do not have INTENT_TYPE sym->hasFlag(FLAG_TYPE_VARIABLE) // 'type' aliases or formals ) { // these are either not variables or not defined outside of 'fn' return false; } Symbol* parent = fn->defPoint->parentSymbol; while (true) { if (!isFnSymbol(parent) && !isModuleSymbol(parent)) return false; if (symParent == parent) return true; if (!parent->defPoint) // Only happens when parent==rootModule (right?). This means symParent // is not in any of the lexically-enclosing functions/modules, so // it's gotta be within 'fn'. return false; // continue to the enclosing scope INT_ASSERT(parent->defPoint->parentSymbol && parent->defPoint->parentSymbol != parent); // ensure termination parent = parent->defPoint->parentSymbol; } }
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; }
// IPE: Provide the name of the symbol/variable being defined const char* DefExpr::name() const { const char* retval = 0; if (isLcnSymbol(sym) == true || isTypeSymbol(sym) == true || isFnSymbol(sym) == true || isModuleSymbol(sym) == true) { retval = sym->name; } return retval; }
// // A forall-intents variation on isOuterVar() in createTaskFunctions.cpp: // Is 'sym' defined outside 'block'? // static bool isOuterVar(Symbol* sym, BlockStmt* block) { if (sym->isParameter() || // includes isImmediate() sym->hasFlag(FLAG_TEMP) || // exclude these // Consts need no special semantics for begin/cobegin/coforall/on. // Implementation-wise, it is uniform with consts in nested functions. sym->hasFlag(FLAG_CONST) || // NB 'type' formals do not have INTENT_TYPE sym->hasFlag(FLAG_TYPE_VARIABLE) // 'type' aliases or formals ) { // these are either not variables or not defined outside of 'fn' return false; } DefExpr* defPt = sym->defPoint; Expr* parentExp = defPt->parentExpr; while (true) { if (!parentExp) { Symbol* parentSym = defPt->parentSymbol; if (isModuleSymbol(parentSym)) // We reached the outermost level and did not come across 'block'. return true; defPt = parentSym->defPoint; parentExp = defPt->parentExpr; continue; } if (parentExp == block) return false; parentExp = parentExp->parentExpr; } INT_ASSERT(false); return false; // dummy }
// // DefExpr // bool AstDumpToHtml::enterDefExpr(DefExpr* node) { bool retval = true; if (isBlockStmt(node->parentExpr)) { fprintf(mFP, "<DL>\n"); } fprintf(mFP, " "); if (FnSymbol* fn = toFnSymbol(node->sym)) { fprintf(mFP, "<UL CLASS =\"mktree\">\n<LI>"); adjacent_passes(fn); fprintf(mFP, "<CHPLTAG=\"FN%d\">\n", fn->id); fprintf(mFP, "<B>function "); writeFnSymbol(fn); fprintf(mFP, "</B><UL>\n"); } else if (isTypeSymbol(node->sym)) { if (toAggregateType(node->sym->type)) { fprintf(mFP, "<UL CLASS =\"mktree\">\n"); fprintf(mFP, "<LI>"); if (node->sym->hasFlag(FLAG_SYNC)) fprintf(mFP, "<B>sync</B> "); if (node->sym->hasFlag(FLAG_SINGLE)) fprintf(mFP, "<B>single</B> "); fprintf(mFP, "<B>type "); writeSymbol(node->sym, true); fprintf(mFP, "</B><UL>\n"); } else { fprintf(mFP, "<B>type </B> "); writeSymbol(node->sym, true); } } else if (VarSymbol* vs = toVarSymbol(node->sym)) { if (vs->type->symbol->hasFlag(FLAG_SYNC)) fprintf(mFP, "<B>sync </B>"); if (vs->type->symbol->hasFlag(FLAG_SINGLE)) fprintf(mFP, "<B>single </B>"); fprintf(mFP, "<B>var </B> "); writeSymbol(node->sym, true); } else if (ArgSymbol* s = toArgSymbol(node->sym)) { switch (s->intent) { case INTENT_IN: fprintf(mFP, "<B>in</B> "); break; case INTENT_INOUT: fprintf(mFP, "<B>inout</B> "); break; case INTENT_OUT: fprintf(mFP, "<B>out</B> "); break; case INTENT_CONST: fprintf(mFP, "<B>const</B> "); break; case INTENT_CONST_IN: fprintf(mFP, "<B>const in</B> "); break; case INTENT_CONST_REF: fprintf(mFP, "<B>const ref</B> "); break; case INTENT_REF: fprintf(mFP, "<B>ref</B> "); break; case INTENT_PARAM: fprintf(mFP, "<B>param</B> "); break; case INTENT_TYPE: fprintf(mFP, "<B>type</B> "); break; case INTENT_BLANK: break; } fprintf(mFP, "<B>arg</B> "); writeSymbol(node->sym, true); } else if (isLabelSymbol(node->sym)) { fprintf(mFP, "<B>label</B> "); writeSymbol(node->sym, true); } else if (isModuleSymbol(node->sym)) { fprintf(mFP, "</DL>\n"); // Don't process nested modules -- they'll be handled at the top-level retval = false; } else { fprintf(mFP, "<B>def</B> "); writeSymbol(node->sym, true); } return retval; }