#include "AST.h" #include "errors.h" #include "code-util.h" #include "tclimits.h" #include "aux-code.h" #include #include #ifdef IRIX #define signal(a,b) bsd_signal(a,b) #endif typedef void (*sighandlerfn_t)(int); sighandlerfn_t reghandler(int sigtocatch, sighandlerfn_t fp) { sighandlerfn_t fpret = (sighandlerfn_t)signal(sigtocatch, fp); if (fpret == (sighandlerfn_t)SIG_ERR) { fprintf(stderr, "Got a SIG_ERR while registering handler for signal %i : %s", sigtocatch,strerror(errno)); return NULL; } #ifdef SIG_HOLD else if (fpret == (sighandlerfn_t)SIG_HOLD) { fprintf(stderr, "Got a SIG_HOLD while registering handler for signal %i : %s", sigtocatch,strerror(errno)); return NULL; } #endif return fpret; } extern string tcCompilerFlags; void outputSettingsInfo(int showargs) { fprintf(stderr, " tc version: %s.%s (%i-bit)\n", tcMajorVersionStr, tcMinorVersionStr, (int)(sizeof(void*)*8)); fflush(stderr); if (showargs) { fprintf(stderr, " tcbuild flags: %s\n", (getenv("TCBUILD_FLAGS")?getenv("TCBUILD_FLAGS"):"???")); fflush(stderr); fprintf(stderr, " tc flags: %s\n", (tcCompilerFlags.c_str()?tcCompilerFlags.c_str():"???")); fflush(stderr); } fprintf(stderr, " machine name: %s\n", TI_SYSTEM_NAME); fflush(stderr); fprintf(stderr, " system type: %s\n", TI_SYSTEM_TUPLE); fflush(stderr); fprintf(stderr, " configured as: %s\n", TI_CONFIGURE_ARGS); fflush(stderr); fprintf(stderr, " build id: %s\n", TI_BUILD_ID); fflush(stderr); if (showargs) { fprintf(stderr, " classlib: %s\n", (getenv("CLASSLIB")?getenv("CLASSLIB"):"")); fflush(stderr); } } void preErrSignalHandler(int sig) { signal(sig, SIG_DFL); /* restore default core-dumping handler */ assert(NumErrors() == 0); fprintf(stderr, "*** Internal Titanium Compiler Error ***\n" "tc has encountered an internal compiler error resulting in fatal signal %i\n" "Please submit a complete bug report here:\n" " http://barnowl.cs.berkeley.edu/cgi-bin/bugdb.cgi (UC Berkeley only)\n" " or by email: \n" " titanium-devel@cs.berkeley.edu\n\n", sig); fflush(stderr); fprintf(stderr, "Include your program code and the following information:\n"); outputSettingsInfo(1); raise(sig); /* re-raise signal to dump core */ } void postErrSignalHandler(int sig) { signal(sig, SIG_DFL); /* restore default core-dumping handler */ assert(NumErrors() > 0); compile_status(1, string("tc exiting abruptly after signal ") + int2string(sig) + string(" (failed with ") + int2string(NumErrors()) + " errors)" ); exit(-1); } void initSigHandlers() { // output a nice helpful message on a crash reghandler(SIGABRT, preErrSignalHandler); reghandler(SIGSEGV, preErrSignalHandler); reghandler(SIGBUS, preErrSignalHandler); reghandler(SIGILL, preErrSignalHandler); #if defined(__alpha) || defined(_CRAYT3E) /* DOB: Setup a trap handler for SIGFPE (floating point exception) to keep it from crashing us (see runtime main.c for details) (constant folding may lead to exceptional FP arithmetic) */ reghandler(SIGFPE, SIG_IGN); #endif } /* Report message at source position N. */ ostream &Message (const SourcePosn N) { return cerr << N << ": "; } static int errorCount = 0; int max_errors = 100; /* Report error at source position N. */ ostream &Error (const SourcePosn N) { if (!errorCount) { // first error - register a segfault handler to ignore // compiler crashes after error (easier than fixing them all) reghandler(SIGABRT, postErrSignalHandler); reghandler(SIGSEGV, postErrSignalHandler); reghandler(SIGBUS, postErrSignalHandler); reghandler(SIGILL, postErrSignalHandler); } errorCount++; if (errorCount >= max_errors) { compile_status(1, string("tc exiting after too many errors ") + string("(failed with ") + int2string(NumErrors()) + " errors)" ); exit(-2); } return Message (N); } extern set suppressed_warnings; /* Report warning at source position N. */ ostream &Warning (const SourcePosn N, const char *messagename) { static ostringstream supressed; if (messagename && strlen(messagename)) { if (suppressed_warnings.count(string(messagename))) return supressed; else return Message( N ) << "warning (" << messagename << "): "; } else { return Message( N ) << "warning: "; } } /* The number of times Error has been called. */ extern int NumErrors() { return errorCount; } static void templateErrorContext(TreeNode const *t, int depth = 0) { set s; while (t && s.count(t) == 0) { s.insert(t); if (isClassDeclNode(t) || isInterfaceDeclNode(t)) { if (t->parent() && isTemplateInstanceDeclNode(t->parent())) { TreeNode *actuals = ((ClassDecl*)(t->decl()))->templateActuals; if (depth < maxTemplateDepth+1) templateErrorContext(actuals, depth+1); string msg = string("While instantiating template: ") + t->decl()->errorName() + ":"; Message(actuals->position()) << msg << endl; } if (t->enclosingType()) { t = t->enclosingType(); continue; } } t = t->parent(); } } ostream &TreeNode::error() const { templateErrorContext(this); return Error( position() ); } ostream &TreeNode::warning( const char *messagename ) const { templateErrorContext(this); return Warning( position(), messagename ); } ostream &TreeNode::message() const { templateErrorContext(this); return Message( position() ); } extern void _fatal_error (const string& msg) { cerr << msg << endl; abort(); }