diff options
author | Ash Wolf <ninji@wuffs.org> | 2023-01-26 11:30:47 +0000 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2023-01-26 11:30:47 +0000 |
commit | 094b96ca1df4a035b5f93c351f773306c0241f3f (patch) | |
tree | 95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/FrontEnd/C/CError.c | |
parent | fc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff) | |
download | MWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.tar.gz MWCC-094b96ca1df4a035b5f93c351f773306c0241f3f.zip |
move lots of source files around to match their actual placement in the original treemain
Diffstat (limited to 'compiler_and_linker/FrontEnd/C/CError.c')
-rw-r--r-- | compiler_and_linker/FrontEnd/C/CError.c | 1098 |
1 files changed, 1098 insertions, 0 deletions
diff --git a/compiler_and_linker/FrontEnd/C/CError.c b/compiler_and_linker/FrontEnd/C/CError.c new file mode 100644 index 0000000..02265c3 --- /dev/null +++ b/compiler_and_linker/FrontEnd/C/CError.c @@ -0,0 +1,1098 @@ +#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); + } +} |