const char* cleanFilename(BaseAST* ast) { const char* astFname = ast->fname(); if (astFname) return cleanFilename(astFname); else if (yyfilename) return cleanFilename(yyfilename); else return astr("<unknown>"); }
const char* cleanFilename(const BaseAST* ast) { const char* retval = NULL; if (const char* astFname = ast->fname()) { retval = cleanFilename(astFname); } else if (yyfilename != NULL) { retval = cleanFilename(yyfilename); } else { retval = astr("<unknown>"); } return retval; }
// // Print the module name, line number, and function signature of each function // on the call stack. This can be called from a debugger to to see what the // call chain looks like e.g. after a resolution error. // void printCallStack(bool force, bool shortModule, FILE* out) { if (!force) { if (!fPrintCallStackOnError || err_print || callStack.n <= 1) return; } if (!developer) fprintf(out, "while processing the following Chapel call chain:\n"); for (int i = callStack.n-1; i >= 0; i--) { CallExpr* call = callStack.v[i]; FnSymbol* fn = call->getFunction(); ModuleSymbol* module = call->getModule(); fprintf(out, " %s:%d: %s%s%s\n", (shortModule ? module->name : cleanFilename(fn->fname())), call->linenum(), toString(fn), (module->modTag == MOD_INTERNAL ? " [internal module]" : ""), (fn->hasFlag(FLAG_COMPILER_GENERATED) ? " [compiler-generated]" : "")); } }
static bool printErrorHeader(const BaseAST* ast) { if (!err_print) { if (const Expr* expr = toConstExpr(ast)) { Symbol* parent = expr->parentSymbol; if (isArgSymbol(parent)) parent = parent->defPoint->parentSymbol; FnSymbol* fn = toFnSymbol(parent); fn = findNonTaskCaller(fn); if (fn && fn != err_fn) { err_fn = fn; while ((fn = toFnSymbol(err_fn->defPoint->parentSymbol))) { if (fn == fn->getModule()->initFn) { break; } err_fn = fn; } // If the function is compiler-generated, or inlined, or doesn't match // the error function and line number, nothing is printed. if (err_fn->getModule()->initFn != err_fn && !err_fn->hasFlag(FLAG_COMPILER_GENERATED) && err_fn->linenum()) { bool suppress = false; // Initializer might be inlined if (err_fn->hasFlag(FLAG_INLINE) == true) { suppress = (strcmp(err_fn->name, "init") != 0) ? true : false; } if (suppress == false) { fprintf(stderr, "%s:%d: In ", cleanFilename(err_fn), err_fn->linenum()); if (strncmp(err_fn->name, "_construct_", 11) == 0) { fprintf(stderr, "initializer '%s':\n", err_fn->name+11); } else if (strcmp(err_fn->name, "init") == 0) { fprintf(stderr, "initializer:\n"); } else { fprintf(stderr, "%s '%s':\n", (err_fn->isIterator() ? "iterator" : "function"), err_fn->name); } } } } } } bool have_ast_line = false; const char* filename; int linenum; if ( ast && ast->linenum() ) { have_ast_line = true; filename = cleanFilename(ast); linenum = ast->linenum(); } else { have_ast_line = false; if ( !err_print && currentAstLoc.filename && currentAstLoc.lineno > 0 ) { // Use our best guess for the line number for user errors, // but don't do that for err_print (USR_PRINT) notes that don't // come with line numbers. filename = cleanFilename(currentAstLoc.filename); linenum = currentAstLoc.lineno; } else { filename = NULL; linenum = -1; } } bool guess = filename && !have_ast_line; if (filename) { fprintf(stderr, "%s:%d: ", filename, linenum); } if (err_print) { fprintf(stderr, "note: "); } else if (err_fatal) { if (err_user) { fprintf(stderr, "error: "); } else { fprintf(stderr, "internal error: "); } } else { fprintf(stderr, "warning: "); } if (!err_user) { if (!developer) { print_user_internal_error(); } } return guess; }