#include "cos.h" #include "compiler/CClass.h" #include "compiler/CError.h" #include "compiler/CFunc.h" #include "compiler/CInt64.h" #include "compiler/CMangler.h" #include "compiler/CParser.h" #include "compiler/CPrep.h" #include "compiler/CPrepTokenizer.h" #include "compiler/CTemplateNew.h" #include "compiler/CompilerTools.h" #include "compiler/InlineAsm.h" #include "compiler/Unmangle.h" #include "compiler/enode.h" #include "compiler/objc.h" #include "compiler/objects.h" #include "compiler/scopes.h" #include "compiler/templates.h" #include "compiler/tokens.h" TStreamElement *cerror_locktoken; static TStreamElement *cerror_token; static short cerror_errorcount; static SInt32 cerror_lasterrorline; char cerror_synchdata[32]; short cerror_synchoffset; int CError_BreakPointcount; // forward decls static void CError_BufferAppendType(CErrorBuffer *eb, Type *ty, UInt32 qual); static void CError_AppendObjectName(CErrorBuffer *eb, Object *obj); void CError_Init(void) { cerror_errorcount = 0; cerror_lasterrorline = -1; cerror_token = 0; cerror_locktoken = 0; } void CError_SetErrorToken(TStreamElement *token) { if (token && token->tokenfile) cerror_token = token; } void CError_SetNullErrorToken(void) { cerror_token = (TStreamElement *) -1; } void CError_LockErrorPos(TStreamElement *token, TStreamElement **saved) { *saved = cerror_locktoken; if (token && token->tokenfile) cerror_locktoken = token; } void CError_UnlockErrorPos(TStreamElement **saved) { cerror_locktoken = *saved; } void CError_ResetErrorSkip(void) { cerror_lasterrorline = -1; } static void CError_GetErrorString(char *buf, short code) { CError_ASSERT(142, code >= CErrorStr100 && code < CErrorStrMAX); COS_GetString(buf, 10000, code - 99); } static void CError_BufferInit(CErrorBuffer *eb, char *buf, SInt32 bufSize) { eb->start = eb->end = buf; eb->size = eb->remaining = bufSize - 1; } static void CError_BufferGrow(CErrorBuffer *eb, SInt32 amount) { char *newBuf; newBuf = lalloc(eb->size + amount); memcpy(newBuf, eb->start, eb->size); eb->start = newBuf; eb->end = newBuf + eb->size - eb->remaining; eb->size += amount; eb->remaining += amount; } static void CError_BufferAppendChar(CErrorBuffer *eb, char ch) { if (eb) { if (!eb->remaining) CError_BufferGrow(eb, 256); *(eb->end++) = ch; eb->remaining--; } } static void CError_BufferAppendString(CErrorBuffer *eb, const char *str) { size_t len; if (eb) { len = strlen(str); if (eb->remaining < len) CError_BufferGrow(eb, len); memcpy(eb->end, str, len); eb->end += len; eb->remaining -= len; } } static void CError_BufferTerminate(CErrorBuffer *eb) { if (eb->remaining == 0) CError_BufferGrow(eb, 1); *eb->end = 0; eb->remaining = 0; } static void CError_BufferAppendQualifier(CErrorBuffer *eb, UInt32 qual) { if (qual & Q_PASCAL) CError_BufferAppendString(eb, "pascal "); if (qual & Q_CONST) CError_BufferAppendString(eb, "const "); if (qual & Q_VOLATILE) CError_BufferAppendString(eb, "volatile "); if (qual & Q_EXPLICIT) CError_BufferAppendString(eb, "explicit "); if (qual & Q_RESTRICT) CError_BufferAppendString(eb, "restrict "); } static void CError_BufferAppendTemplArgExpr(CErrorBuffer *eb, ENode *node) { char buf[32]; if (node) { switch (node->type) { case EINTCONST: CInt64_PrintDec(buf, node->data.intval); CError_BufferAppendString(eb, buf); return; case EOBJREF: CError_BufferAppendChar(eb, '&'); CError_AppendObjectName(eb, node->data.objref); return; } } CError_BufferAppendString(eb, "{targ_expr}"); } static void CError_BufferAppendTemplArg(CErrorBuffer *eb, TemplArg *targ) { switch (targ->pid.type) { case TPT_TYPE: CError_BufferAppendType(eb, targ->data.typeparam.type, targ->data.typeparam.qual); break; case TPT_NONTYPE: CError_BufferAppendTemplArgExpr(eb, targ->data.paramdecl.expr); break; case TPT_TEMPLATE: CError_BufferAppendType(eb, targ->data.ttargtype, 0); break; default: CError_FATAL(300); } } static void CError_BufferAppendTemplArgs(CErrorBuffer *eb, TemplArg *targs) { if (targs) { CError_BufferAppendChar(eb, '<'); while (targs) { CError_BufferAppendTemplArg(eb, targs); if (targs->next) CError_BufferAppendString(eb, ", "); targs = targs->next; } CError_BufferAppendChar(eb, '>'); } } static void CError_BufferAppendNameSpace(CErrorBuffer *eb, NameSpace *nspace) { while (nspace) { if (nspace->name) { CError_BufferAppendNameSpace(eb, nspace->parent); if (nspace->theclass) { CError_BufferAppendString(eb, nspace->theclass->classname->name); if (nspace->theclass->flags & CLASS_IS_TEMPL_INST) CError_BufferAppendTemplArgs( eb, !TEMPL_CLASS_INST(nspace->theclass)->oargs ? TEMPL_CLASS_INST(nspace->theclass)->inst_args : TEMPL_CLASS_INST(nspace->theclass)->oargs ); } else { CError_BufferAppendString(eb, nspace->name->name); } CError_BufferAppendString(eb, "::"); return; } nspace = nspace->parent; } } static void CError_BufferAppendPType(CErrorBuffer *eb, Type *ty) { switch (ty->type) { case TYPEPOINTER: CError_BufferAppendPType(eb, TYPE_POINTER(ty)->target); if (TYPE_POINTER(ty)->qual & Q_REFERENCE) CError_BufferAppendString(eb, "&"); else CError_BufferAppendString(eb, "*"); CError_BufferAppendQualifier(eb, TYPE_POINTER(ty)->qual); break; case TYPEMEMBERPOINTER: CError_BufferAppendPType(eb, TYPE_MEMBER_POINTER(ty)->ty1); CError_BufferAppendType(eb, TYPE_MEMBER_POINTER(ty)->ty2, 0); CError_BufferAppendString(eb, "::*"); CError_BufferAppendQualifier(eb, TYPE_MEMBER_POINTER(ty)->qual); break; } } static void CError_BufferAppendTemplDepType(CErrorBuffer *eb, TypeTemplDep *type) { char buf[64]; switch (type->dtype) { case TEMPLDEP_ARGUMENT: if (type->u.pid.nindex) sprintf(buf, "T%" PRId32 "_%" PRId32, type->u.pid.nindex, type->u.pid.index); else sprintf(buf, "T%" PRId32, type->u.pid.index); CError_BufferAppendString(eb, buf); break; case TEMPLDEP_QUALNAME: CError_BufferAppendTemplDepType(eb, type->u.qual.type); CError_BufferAppendString(eb, "::"); CError_BufferAppendString(eb, type->u.qual.name->name); break; case TEMPLDEP_TEMPLATE: CError_BufferAppendType(eb, (Type *) type->u.templ.templ, 0); CError_BufferAppendTemplArgs(eb, type->u.templ.args); break; case TEMPLDEP_ARRAY: CError_BufferAppendType(eb, type->u.array.type, 0); CError_BufferAppendChar(eb, '['); CError_BufferAppendTemplArgExpr(eb, type->u.array.index); CError_BufferAppendChar(eb, ']'); break; case TEMPLDEP_QUALTEMPL: CError_BufferAppendTemplDepType(eb, type->u.qualtempl.type); CError_BufferAppendString(eb, "::"); CError_BufferAppendTemplArgs(eb, type->u.qualtempl.args); break; case TEMPLDEP_BITFIELD: CError_BufferAppendType(eb, type->u.bitfield.type, 0); CError_BufferAppendChar(eb, '['); CError_BufferAppendTemplArgExpr(eb, type->u.bitfield.size); CError_BufferAppendChar(eb, ']'); break; default: CError_FATAL(463); } } static void CError_BufferAppendFuncArgs(CErrorBuffer *eb, TypeFunc *tfunc, Boolean isMethod) { FuncArg *arg; UInt32 qual; qual = 0; CError_BufferAppendChar(eb, '('); if ((arg = tfunc->args)) { if (isMethod) { qual = arg->qual; arg = arg->next; if (arg) arg = arg->next; } else if ((tfunc->flags & FUNC_METHOD) && !TYPE_METHOD(tfunc)->is_static) { qual = arg->qual; arg = arg->next; if (arg) { if ((tfunc->flags & FUNC_IS_DTOR) || ((tfunc->flags & FUNC_IS_CTOR) && (TYPE_METHOD(tfunc)->theclass->flags & CLASS_HAS_VBASES))) arg = arg->next; } } while (arg) { if (arg == &elipsis || arg == &oldstyle) { CError_BufferAppendString(eb, "..."); break; } CError_BufferAppendType(eb, arg->type, arg->qual); if ((arg = arg->next)) CError_BufferAppendString(eb, ", "); else break; } } CError_BufferAppendChar(eb, ')'); if (qual) CError_BufferAppendQualifier(eb, qual); } static void CError_BufferAppendType(CErrorBuffer *eb, Type *ty, UInt32 qual) { // not matching - register issues Type *scan; Type *scan2; char buf[16]; switch (ty->type) { case TYPEVOID: CError_BufferAppendQualifier(eb, qual); CError_BufferAppendString(eb, "void"); return; case TYPEINT: case TYPEFLOAT: CError_BufferAppendQualifier(eb, qual); switch (TYPE_INTEGRAL(ty)->integral) { case IT_BOOL: CError_BufferAppendString(eb, "bool"); return; case IT_CHAR: CError_BufferAppendString(eb, "char"); return; case IT_UCHAR: CError_BufferAppendString(eb, "unsigned char"); return; case IT_SCHAR: CError_BufferAppendString(eb, "signed char"); return; case IT_WCHAR_T: CError_BufferAppendString(eb, "wchar_t"); return; case IT_SHORT: CError_BufferAppendString(eb, "short"); return; case IT_USHORT: CError_BufferAppendString(eb, "unsigned short"); return; case IT_INT: CError_BufferAppendString(eb, "int"); return; case IT_UINT: CError_BufferAppendString(eb, "unsigned int"); return; case IT_LONG: CError_BufferAppendString(eb, "long"); return; case IT_ULONG: CError_BufferAppendString(eb, "unsigned long"); return; case IT_LONGLONG: CError_BufferAppendString(eb, "long long"); return; case IT_ULONGLONG: CError_BufferAppendString(eb, "unsigned long long"); return; case IT_FLOAT: CError_BufferAppendString(eb, "float"); return; case IT_SHORTDOUBLE: CError_BufferAppendString(eb, "short double"); return; case IT_DOUBLE: CError_BufferAppendString(eb, "double"); return; case IT_LONGDOUBLE: CError_BufferAppendString(eb, "long double"); return; default: CError_FATAL(584); } case TYPEENUM: CError_BufferAppendQualifier(eb, qual); CError_BufferAppendNameSpace(eb, TYPE_ENUM(ty)->nspace); if (TYPE_ENUM(ty)->enumname) CError_BufferAppendString(eb, TYPE_ENUM(ty)->enumname->name); else CError_BufferAppendString(eb, "{unnamed-enum}"); return; case TYPESTRUCT: CError_BufferAppendQualifier(eb, qual); switch (TYPE_STRUCT(ty)->stype) { case STRUCT_TYPE_STRUCT: CError_BufferAppendString(eb, "struct "); break; case STRUCT_TYPE_UNION: CError_BufferAppendString(eb, "union "); break; case STRUCT_VECTOR_UCHAR: case STRUCT_VECTOR_SCHAR: case STRUCT_VECTOR_BCHAR: case STRUCT_VECTOR_USHORT: case STRUCT_VECTOR_SSHORT: case STRUCT_VECTOR_BSHORT: case STRUCT_VECTOR_UINT: case STRUCT_VECTOR_SINT: case STRUCT_VECTOR_BINT: case STRUCT_VECTOR_FLOAT: case STRUCT_VECTOR_PIXEL: break; default: CError_FATAL(618); } if (TYPE_STRUCT(ty)->name) CError_BufferAppendString(eb, TYPE_STRUCT(ty)->name->name); return; case TYPECLASS: CError_BufferAppendQualifier(eb, qual); CError_BufferAppendNameSpace(eb, TYPE_CLASS(ty)->nspace->parent); if (TYPE_CLASS(ty)->classname) { CError_BufferAppendString(eb, TYPE_CLASS(ty)->classname->name); if (TYPE_CLASS(ty)->flags & CLASS_IS_TEMPL_INST) CError_BufferAppendTemplArgs( eb, TEMPL_CLASS_INST(ty)->oargs ? TEMPL_CLASS_INST(ty)->oargs : TEMPL_CLASS_INST(ty)->inst_args ); } else { CError_BufferAppendString(eb, "{unnamed-class}"); } return; case TYPEPOINTER: case TYPEMEMBERPOINTER: scan = ty; next_ptr: switch (scan->type) { case TYPEPOINTER: scan = TYPE_POINTER(scan)->target; goto next_ptr; case TYPEMEMBERPOINTER: scan = TYPE_MEMBER_POINTER(scan)->ty1; goto next_ptr; } CError_BufferAppendQualifier(eb, qual); switch (scan->type) { case TYPEFUNC: if (TYPE_FUNC(scan)->flags & FUNC_PASCAL) CError_BufferAppendString(eb, "pascal "); CError_BufferAppendType(eb, TYPE_FUNC(scan)->functype, 0); CError_BufferAppendString(eb, " ("); CError_BufferAppendPType(eb, ty); CError_BufferAppendChar(eb, ')'); CError_BufferAppendFuncArgs(eb, TYPE_FUNC(scan), ty->type == TYPEMEMBERPOINTER); return; case TYPEARRAY: scan2 = scan; while (scan->type == TYPEARRAY) scan = TYPE_POINTER(scan)->target; CError_BufferAppendType(eb, scan, 0); CError_BufferAppendString(eb, " ("); CError_BufferAppendPType(eb, ty); CError_BufferAppendChar(eb, ')'); ty = scan2; goto append_array_lengths; default: CError_BufferAppendType(eb, scan, 0); CError_BufferAppendChar(eb, ' '); CError_BufferAppendPType(eb, ty); return; } break; case TYPEFUNC: if (TYPE_FUNC(ty)->flags & FUNC_PASCAL) CError_BufferAppendString(eb, "pascal "); CError_BufferAppendQualifier(eb, qual); CError_BufferAppendType(eb, TYPE_FUNC(ty)->functype, 0); CError_BufferAppendChar(eb, ' '); CError_BufferAppendFuncArgs(eb, TYPE_FUNC(ty), 0); return; case TYPEARRAY: CError_BufferAppendQualifier(eb, qual); scan = ty; while (scan->type == TYPEARRAY) scan = TYPE_POINTER(scan)->target; CError_BufferAppendType(eb, scan, 0); append_array_lengths: while (ty->type == TYPEARRAY) { CError_BufferAppendChar(eb, '['); if (ty->size && TYPE_POINTER(ty)->target->size) { sprintf(buf, "%" PRId32, ty->size / TYPE_POINTER(ty)->target->size); CError_BufferAppendString(eb, buf); } CError_BufferAppendChar(eb, ']'); ty = TYPE_POINTER(ty)->target; } return; case TYPETEMPLATE: CError_BufferAppendQualifier(eb, qual); CError_BufferAppendTemplDepType(eb, TYPE_TEMPLATE(ty)); return; case TYPETEMPLDEPEXPR: CError_BufferAppendString(eb, "T"); return; case TYPEBITFIELD: sprintf(buf, "bitfield:%" PRId32, TYPE_BITFIELD(ty)->bitlength); CError_BufferAppendString(eb, buf); return; default: CError_FATAL(752); } } char *CError_GetTypeName(Type *ty, UInt32 qual, Boolean useGlobalHeap) { CErrorBuffer eb; char buf[256]; char *ptr; CError_BufferInit(&eb, buf, sizeof(buf)); CError_BufferAppendType(&eb, ty, qual); CError_BufferTerminate(&eb); if (useGlobalHeap) ptr = galloc(eb.size + 1); else ptr = lalloc(eb.size + 1); return strcpy(ptr, eb.start); } static void CError_AppendUnqualFunctionName(CErrorBuffer *eb, NameSpace *nspace, HashNameNode *name, TypeFunc *tfunc) { Boolean flag = 0; char *opname; if (nspace && nspace->theclass) { if (name == constructor_name_node) { CError_BufferAppendString(eb, nspace->theclass->classname->name); flag = 1; } else if (name == destructor_name_node) { CError_BufferAppendChar(eb, '~'); CError_BufferAppendString(eb, nspace->theclass->classname->name); flag = 1; } } if (!flag) { opname = CMangler_GetOperator(name); if (!opname) { if (tfunc && (tfunc->flags & FUNC_CONVERSION)) { CError_BufferAppendString(eb, "operator "); CError_BufferAppendType(eb, tfunc->functype, tfunc->qual); } else { CError_BufferAppendString(eb, name->name); } } else { CError_BufferAppendString(eb, opname); } } } static void CError_AppendFunctionName(CErrorBuffer *eb, NameSpace *nspace, HashNameNode *name, TemplArg *templargs, TypeFunc *tfunc) { while (nspace->is_templ && nspace->parent) nspace = nspace->parent; CError_BufferAppendNameSpace(eb, nspace); CError_AppendUnqualFunctionName(eb, nspace, name, tfunc); CError_BufferAppendTemplArgs(eb, templargs); if (tfunc) { if (!templargs && (tfunc->flags & FUNC_IS_TEMPL)) CError_BufferAppendString(eb, "<...>"); CError_BufferAppendFuncArgs(eb, tfunc, 0); } else { CError_BufferAppendString(eb, "()"); } } static void CError_AppendObjectName(CErrorBuffer *eb, Object *obj) { if (obj->type->type == TYPEFUNC) { CError_AppendFunctionName(eb, obj->nspace, obj->name, obj->u.func.inst ? obj->u.func.inst->args : NULL, TYPE_FUNC(obj->type)); } else { CError_BufferAppendNameSpace(eb, obj->nspace); CError_BufferAppendString(eb, obj->name->name); } } static void CError_AppendMethodName(CErrorBuffer *eb, ObjCMethod *meth) { ObjCMethodArg *arg; CError_BufferAppendChar(eb, meth->is_class_method ? '+' : '-'); CError_BufferAppendChar(eb, '('); CError_BufferAppendType(eb, meth->return_type, meth->return_qual); CError_BufferAppendChar(eb, ')'); for (arg = meth->selector_args; arg; arg = arg->next) { if (arg->selector) CError_BufferAppendString(eb, arg->selector->name); if (arg->type) { CError_BufferAppendString(eb, ":("); CError_BufferAppendType(eb, arg->type, arg->qual); CError_BufferAppendChar(eb, ')'); } } if (meth->has_valist) CError_BufferAppendString(eb, ",..."); } char *CError_GetQualifiedName(NameSpace *nspace, HashNameNode *name) { CErrorBuffer eb; char buf[256]; char *ptr; CError_BufferInit(&eb, buf, sizeof(buf)); CError_BufferAppendNameSpace(&eb, nspace); CError_BufferAppendString(&eb, name->name); CError_BufferTerminate(&eb); ptr = lalloc(eb.size + 1); return strcpy(ptr, eb.start); } char *CError_GetFunctionName(NameSpace *nspace, HashNameNode *name, TypeFunc *tfunc) { CErrorBuffer eb; char buf[256]; char *ptr; CError_BufferInit(&eb, buf, sizeof(buf)); CError_AppendFunctionName(&eb, nspace, name, 0, tfunc); CError_BufferTerminate(&eb); ptr = lalloc(eb.size + 1); return strcpy(ptr, eb.start); } char *CError_GetObjectName(Object *obj) { CErrorBuffer eb; char buf[256]; char *ptr; CError_BufferInit(&eb, buf, sizeof(buf)); CError_AppendObjectName(&eb, obj); CError_BufferTerminate(&eb); ptr = lalloc(eb.size + 1); return strcpy(ptr, eb.start); } char *CError_GetNameString(NameSpace *nspace, HashNameNode *operatorName) { CErrorBuffer eb; char buf[256]; char *ptr; char *opStr; CError_ASSERT(973, operatorName); opStr = CMangler_GetOperator(operatorName); if (!opStr) opStr = operatorName->name; if (nspace && nspace->name) { CError_BufferInit(&eb, buf, sizeof(buf)); CError_BufferAppendNameSpace(&eb, nspace); CError_BufferAppendString(&eb, opStr); CError_BufferTerminate(&eb); ptr = lalloc(eb.size + 1); return strcpy(ptr, eb.start); } else { return opStr; } } void CError_ErrorMessage(int errTable, char *str, Boolean flag1, Boolean flag2) { TStreamElement *token; short tokensize; CPrepFileInfo *tokenfile; CWMessageRef myref; char buf[128]; CWMessageRef *ref; unsigned char messagetype; if (CWDisplayLines(cparamblkptr->context, lines) != cwNoErr) CError_UserBreak(); if (!in_assembler && !flag1 && cerror_lasterrorline == lines) { if (cerror_errorcount++ >= 50) { if (cerror_errorcount > 60) longjmp(errorreturn, 1); tk = lex(); cerror_errorcount = 0; if (tk == 0) { CompilerGetCString(1, buf); CWReportMessage(cparamblkptr->context, NULL, buf, NULL, messagetypeError, errTable); longjmp(errorreturn, 1); } } } else { if (!flag2) { cerror_lasterrorline = lines; cerror_errorcount = 0; } if (copts.warningerrors) flag2 = 0; if (cerror_token) token = cerror_token; else if (cerror_locktoken) token = cerror_locktoken; else token = NULL; //token = cerror_token ? cerror_token : cerror_locktoken ? cerror_locktoken : NULL; if ((SInt32) token == -1) { ref = NULL; } else { CPrep_GetTokenContext(token, &tokenfile, &myref.selectionoffset, &tokensize, &myref.linenumber, buf, &myref.tokenoffset, &myref.tokenlength, cerror_synchdata, &cerror_synchoffset); myref.selectionlength = tokensize; myref.sourcefile = tokenfile->textfile; ref = &myref; } messagetype = flag2 ? messagetypeWarning : messagetypeError; if (!flag2) { anyerrors = 1; fatalerrors = 1; } if (CWReportMessage(cparamblkptr->context, ref, str, buf, messagetype, errTable) != cwNoErr) longjmp(errorreturn, 1); } cerror_token = NULL; } static void CError_BufferAppendTemplateStack(CErrorBuffer *eb) { TemplStack *stack[64]; TemplStack *scan; int index; int indent; int count; scan = ctempl_curinstance; for (count = 0; scan && count < 64; count++) { stack[count] = scan; scan = scan->next; } for (index = count - 1; index >= 0; index--) { CError_BufferAppendChar(eb, LF); for (indent = index; indent < count; indent++) CError_BufferAppendChar(eb, ' '); CError_BufferAppendString(eb, "(instantiating: '"); if (stack[index]->is_func) CError_AppendObjectName(eb, stack[index]->u.func); else CError_BufferAppendType(eb, (Type *) stack[index]->u.theclass, 0); CError_BufferAppendString(eb, "')"); } CError_BufferTerminate(eb); } void CError_ErrorMessageVA(int code, const char *format, va_list list, Boolean flag1, Boolean flag2) { // register allocation is fucked, matches otherwise CErrorBuffer eb; char buf[256]; char unmangleBuf[256]; SInt32 moddate; Type *type; UInt32 qual; const char *p; CError_BufferInit(&eb, buf, sizeof(buf)); p = format; do { switch (p[0]) { case 0: break; case '%': switch (p[1]) { case 'n': MWUnmangle(va_arg(list, const char *), unmangleBuf, sizeof(unmangleBuf)); CError_BufferAppendString(&eb, unmangleBuf); p += 2; continue; case 'u': CError_BufferAppendString(&eb, va_arg(list, const char *)); p += 2; continue; case 'o': CError_AppendObjectName(&eb, va_arg(list, Object *)); p += 2; continue; case 'm': CError_AppendMethodName(&eb, va_arg(list, ObjCMethod *)); p += 2; continue; case 't': type = va_arg(list, Type *); qual = va_arg(list, UInt32); CError_BufferAppendType(&eb, type, qual); p += 2; continue; case '%': CError_BufferAppendChar(&eb, '%'); p += 2; continue; case 'i': sprintf(unmangleBuf, "%" PRId32, va_arg(list, SInt32)); CError_BufferAppendString(&eb, unmangleBuf); p += 2; continue; case 'f': CError_BufferAppendString(&eb, CTool_GetPathName(va_arg(list, FSSpec *), &moddate)->name); p += 2; continue; default: CError_FATAL(1174); } break; default: CError_BufferAppendChar(&eb, *(p++)); continue; } break; } while (1); CError_BufferAppendTemplateStack(&eb); CError_ErrorMessage(code, eb.start, flag1, flag2); } static void CError_VAErrorMessage(int code, va_list list, Boolean flag1, Boolean flag2) { char buf[256]; CError_GetErrorString(buf, code); CError_ErrorMessageVA(code + 10000, buf, list, flag1, flag2); } void CError_Error(int code, ...) { va_list va; if (trychain) longjmp(trychain->jmpbuf, 1); va_start(va, code); CError_VAErrorMessage(code, va, 0, 0); va_end(va); if (in_assembler && !preprocessing_only) AssemblerError(); } void CError_ErrorTerm(short code) { CError_GetErrorString(string, code); CError_ErrorMessage(code + 10000, string, 0, 0); longjmp(errorreturn, 1); } void CError_ErrorSkip(int code, ...) { va_list va; if (trychain) longjmp(trychain->jmpbuf, 1); va_start(va, code); CError_VAErrorMessage(code, va, 0, 0); va_end(va); if (tk != ';' && tk != ')' && tk != '}' && tk != ',' && tk != ']') tk = lex(); } void CError_ErrorFuncCall(short code, NameSpaceObjectList *args, ENodeList *argNodes) { // does not match - one branch has loop weirdness CErrorBuffer eb; char buf[256]; char *p; ENodeList *argscan; if (trychain) longjmp(trychain->jmpbuf, 1); CError_GetErrorString(string, code); CError_BufferInit(&eb, buf, sizeof(buf)); while (args && args->object->otype != OT_OBJECT) args = args->next; CError_ASSERT(1268, args); p = string; do { switch (*p) { case 0: goto exit_main_loop; case '*': if (OBJECT(args->object)->type->type == TYPEFUNC) { CError_AppendUnqualFunctionName( &eb, OBJECT(args->object)->nspace, OBJECT(args->object)->name, TYPE_FUNC(OBJECT(args->object)->type)); if (TYPE_FUNC(OBJECT(args->object)->type)->flags & FUNC_METHOD) if (TYPE_FUNC(OBJECT(args->object)->type)->flags & FUNC_IS_CTOR) if (TYPE_METHOD(OBJECT(args->object)->type)->theclass->flags & CLASS_HAS_VBASES) if (argNodes) argNodes = argNodes->next; } else { CError_BufferAppendString(&eb, OBJECT(args->object)->name->name); } CError_BufferAppendChar(&eb, '('); argscan = argNodes; while (argscan) { CError_BufferAppendType(&eb, argscan->node->rtype, argscan->node->flags & ENODE_FLAG_QUALS); if ((argscan = argscan->next)) CError_BufferAppendString(&eb, ", "); else break; } CError_BufferAppendChar(&eb, ')'); break; default: CError_BufferAppendChar(&eb, *p); } p++; } while (1); exit_main_loop: while (args) { if (args->object->otype == OT_OBJECT) { CError_BufferAppendChar(&eb, LF); CError_BufferAppendChar(&eb, '\''); CError_AppendObjectName(&eb, (Object *) args->object); CError_BufferAppendChar(&eb, '\''); } args = args->next; } CError_BufferAppendTemplateStack(&eb); CError_ErrorMessage(10000 + code, eb.start, 0, 0); } void CError_OverloadedFunctionError2(Object *obj, ObjectList *olst, ENodeList *argNodes) { // not sure if the arg is actually ObjectList since it's never called lmao NameSpaceObjectList first; NameSpaceObjectList *current; first.object = (ObjBase *) obj; current = &first; while (olst) { current->next = lalloc(sizeof(NameSpaceObjectList)); current = current->next; current->object = (ObjBase *) olst->object; olst = olst->next; } current->next = NULL; CError_ErrorFuncCall(CErrorStr392, &first, argNodes); } void CError_OverloadedFunctionError(Object *obj, ObjectList *olst) { // not sure if this arg is ObjectList or NameSpaceObjectList CErrorBuffer eb; char buf[256]; if (trychain) longjmp(trychain->jmpbuf, 1); CError_GetErrorString(string, CErrorStr199); CError_BufferInit(&eb, buf, sizeof(buf)); CError_BufferAppendString(&eb, string); if (obj) { CError_BufferAppendChar(&eb, LF); CError_BufferAppendChar(&eb, '\''); CError_AppendObjectName(&eb, obj); CError_BufferAppendChar(&eb, '\''); } while (olst) { CError_BufferAppendChar(&eb, LF); CError_BufferAppendChar(&eb, '\''); CError_AppendObjectName(&eb, olst->object); CError_BufferAppendChar(&eb, '\''); olst = olst->next; } CError_BufferAppendTemplateStack(&eb); CError_ErrorMessage(10199, eb.start, 0, 0); } void CError_AbstractClassError(TypeClass *tclass) { Object *result = CClass_CheckPures(tclass); if (!result) CError_Error(CErrorStr372, tclass, 0); else CError_Error(CErrorStr194, result); } void CError_Warning(int code, ...) { va_list va; if (trychain || copts.supress_warnings) return; va_start(va, code); CError_VAErrorMessage(code, va, 0, 1); va_end(va); } void CError_BreakPoint(const char *a, const char *b) { if (!a || !strcmp(a, b)) CError_BreakPointcount++; } void CError_Internal(char *filename, int line) { char tmp[128]; CompilerGetCString(5, tmp); sprintf(string, tmp, filename, line); CError_ErrorMessage(10001, string, 1, 0); longjmp(errorreturn, 1); CError_BreakPoint(0, 0); } void CError_ExpressionTooComplex(void) { CompilerGetCString(6, string); CError_ErrorMessage(10002, string, 1, 0); longjmp(errorreturn, 1); } void CError_NoMem(void) { cprep_nomem_exit = 1; longjmp(errorreturn, 1); } void CError_UserBreak(void) { CompilerGetCString(8, string); longjmp(errorreturn, 1); } void CError_CannotOpen(void) { CompilerGetCString(9, string); CWReportMessage(cparamblkptr->context, NULL, string, NULL, messagetypeError, 0); longjmp(errorreturn, 1); } void CError_QualifierCheck(UInt32 qual) { if (qual) { Boolean anything = 0; if (qual & Q_CONST) { CError_Error(CErrorStr313, "const"); anything = 1; } if (qual & Q_VOLATILE) { CError_Error(CErrorStr313, "volatile"); anything = 1; } if (qual & Q_RESTRICT) { CError_Error(CErrorStr313, "restrict"); anything = 1; } if (qual & Q_ASM) { CError_Error(CErrorStr313, "asm"); anything = 1; } if (qual & Q_PASCAL) { CError_Error(CErrorStr313, "pascal"); anything = 1; } if (qual & Q_INLINE) { CError_Error(CErrorStr313, "inline"); anything = 1; } if (qual & Q_REFERENCE) { CError_Error(CErrorStr313, "& reference type"); anything = 1; } if (qual & Q_EXPLICIT) { CError_Error(CErrorStr313, "explicit"); anything = 1; } if (qual & Q_MUTABLE) { CError_Error(CErrorStr313, "mutable"); anything = 1; } if (qual & Q_VIRTUAL) { CError_Error(CErrorStr313, "virtual"); anything = 1; } if (qual & Q_FRIEND) { CError_Error(CErrorStr313, "friend"); anything = 1; } if (qual & Q_IN) { CError_Error(CErrorStr313, "in"); anything = 1; } if (qual & Q_OUT) { CError_Error(CErrorStr313, "out"); anything = 1; } if (qual & Q_INOUT) { CError_Error(CErrorStr313, "inout"); anything = 1; } if (qual & Q_BYCOPY) { CError_Error(CErrorStr313, "bycopy"); anything = 1; } if (qual & Q_BYREF) { CError_Error(CErrorStr313, "byref"); anything = 1; } if (qual & Q_ONEWAY) { CError_Error(CErrorStr313, "oneway"); anything = 1; } if (qual & Q_ALIGNED_MASK) { CError_Error(CErrorStr313, "__attribute__((aligned(?)))"); anything = 1; } if (!anything) CError_Error(CErrorStr176); } }