MWCC/compiler_and_linker/unsorted/CError.c

1095 lines
35 KiB
C
Raw Normal View History

2022-10-25 19:30:28 +00:00
#include "cos.h"
2022-12-29 12:32:55 +00:00
#include "compiler/CClass.h"
2022-10-25 19:30:28 +00:00
#include "compiler/CError.h"
2022-12-29 12:32:55 +00:00
#include "compiler/CFunc.h"
2022-10-25 19:30:28 +00:00
#include "compiler/CInt64.h"
2022-12-29 12:32:55 +00:00
#include "compiler/CMangler.h"
#include "compiler/CParser.h"
#include "compiler/CPrep.h"
#include "compiler/CPrepTokenizer.h"
#include "compiler/CTemplateNew.h"
2022-10-25 19:30:28 +00:00
#include "compiler/CompilerTools.h"
2022-12-29 12:32:55 +00:00
#include "compiler/InlineAsm.h"
#include "compiler/Unmangle.h"
2022-10-25 19:30:28 +00:00
#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;
2023-01-11 22:29:53 +00:00
void CError_Init(void) {
2022-10-25 19:30:28 +00:00
cerror_errorcount = 0;
cerror_lasterrorline = -1;
cerror_token = 0;
cerror_locktoken = 0;
}
void CError_SetErrorToken(TStreamElement *token) {
if (token && token->tokenfile)
cerror_token = token;
}
2023-01-11 22:29:53 +00:00
void CError_SetNullErrorToken(void) {
2022-10-25 19:30:28 +00:00
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;
}
2023-01-11 22:29:53 +00:00
void CError_ResetErrorSkip(void) {
2022-10-25 19:30:28 +00:00
cerror_lasterrorline = -1;
}
void CError_GetErrorString(char *buf, short code) {
2022-12-29 12:32:55 +00:00
CError_ASSERT(142, code >= CErrorStr100 && code < CErrorStrMAX);
2022-10-25 19:30:28 +00:00
COS_GetString(buf, 10000, code - 99);
}
void CError_BufferInit(CErrorBuffer *eb, char *buf, SInt32 bufSize) {
eb->start = eb->end = buf;
eb->size = eb->remaining = bufSize - 1;
}
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;
}
void CError_BufferAppendChar(CErrorBuffer *eb, char ch) {
if (eb) {
if (!eb->remaining)
CError_BufferGrow(eb, 256);
*(eb->end++) = ch;
eb->remaining--;
}
}
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;
}
}
void CError_BufferTerminate(CErrorBuffer *eb) {
if (eb->remaining == 0)
CError_BufferGrow(eb, 1);
*eb->end = 0;
eb->remaining = 0;
}
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 ");
}
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}");
}
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:
2022-12-29 12:32:55 +00:00
CError_FATAL(300);
2022-10-25 19:30:28 +00:00
}
}
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, '>');
}
}
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_FLAGS_800)
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;
}
}
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;
}
}
void CError_BufferAppendTemplDepType(CErrorBuffer *eb, TypeTemplDep *type) {
char buf[64];
switch (type->dtype) {
case TEMPLDEP_ARGUMENT:
if (type->u.pid.nindex)
2023-01-14 13:20:48 +00:00
sprintf(buf, "T%" PRId32 "%" PRId32, type->u.pid.nindex, type->u.pid.index);
2022-10-25 19:30:28 +00:00
else
2023-01-14 13:20:48 +00:00
sprintf(buf, "T%" PRId32, type->u.pid.index);
2022-10-25 19:30:28 +00:00
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:
2022-12-29 12:32:55 +00:00
CError_FATAL(463);
2022-10-25 19:30:28 +00:00
}
}
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_FLAGS_METHOD) && !TYPE_METHOD(tfunc)->x26) {
qual = arg->qual;
arg = arg->next;
if (arg) {
if ((tfunc->flags & FUNC_FLAGS_2000) || ((tfunc->flags & FUNC_FLAGS_1000) && (TYPE_METHOD(tfunc)->theclass->flags & CLASS_FLAGS_20)))
arg = arg->next;
}
}
while (arg) {
if (arg == &elipsis || arg == &oldstyle) {
CError_BufferAppendString(eb, "...");
break;
}
2023-01-10 11:05:21 +00:00
CError_BufferAppendType(eb, arg->type, arg->qual);
if ((arg = arg->next))
2022-10-25 19:30:28 +00:00
CError_BufferAppendString(eb, ", ");
2023-01-10 11:05:21 +00:00
else
2022-10-25 19:30:28 +00:00
break;
}
}
CError_BufferAppendChar(eb, ')');
if (qual)
CError_BufferAppendQualifier(eb, qual);
}
void CError_BufferAppendType(CErrorBuffer *eb, Type *ty, UInt32 qual) {
// not matching - register issues
2023-01-10 11:05:21 +00:00
Type *scan;
Type *scan2;
2022-10-25 19:30:28 +00:00
char buf[16];
switch (ty->type) {
case TYPEVOID:
CError_BufferAppendQualifier(eb, qual);
CError_BufferAppendString(eb, "void");
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
case TYPEINT:
case TYPEFLOAT:
CError_BufferAppendQualifier(eb, qual);
switch (TYPE_INTEGRAL(ty)->integral) {
case IT_BOOL:
CError_BufferAppendString(eb, "bool");
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
case IT_CHAR:
CError_BufferAppendString(eb, "char");
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
case IT_UCHAR:
CError_BufferAppendString(eb, "unsigned char");
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
case IT_SCHAR:
CError_BufferAppendString(eb, "signed char");
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
case IT_WCHAR_T:
CError_BufferAppendString(eb, "wchar_t");
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
case IT_SHORT:
CError_BufferAppendString(eb, "short");
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
case IT_USHORT:
CError_BufferAppendString(eb, "unsigned short");
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
case IT_INT:
CError_BufferAppendString(eb, "int");
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
case IT_UINT:
CError_BufferAppendString(eb, "unsigned int");
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
case IT_LONG:
CError_BufferAppendString(eb, "long");
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
case IT_ULONG:
CError_BufferAppendString(eb, "unsigned long");
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
case IT_LONGLONG:
CError_BufferAppendString(eb, "long long");
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
case IT_ULONGLONG:
CError_BufferAppendString(eb, "unsigned long long");
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
case IT_FLOAT:
CError_BufferAppendString(eb, "float");
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
case IT_SHORTDOUBLE:
CError_BufferAppendString(eb, "short double");
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
case IT_DOUBLE:
CError_BufferAppendString(eb, "double");
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
case IT_LONGDOUBLE:
CError_BufferAppendString(eb, "long double");
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
default:
2022-12-29 12:32:55 +00:00
CError_FATAL(584);
2022-10-25 19:30:28 +00:00
}
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}");
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
case TYPESTRUCT:
CError_BufferAppendQualifier(eb, qual);
switch (TYPE_STRUCT(ty)->stype) {
case STRUCT_TYPE_STRUCT:
CError_BufferAppendString(eb, "struct ");
break;
case STRUCT_TYPE_UNION:
2023-01-10 11:05:21 +00:00
CError_BufferAppendString(eb, "union ");
2022-10-25 19:30:28 +00:00
break;
case STRUCT_TYPE_4:
case STRUCT_TYPE_5:
case STRUCT_TYPE_6:
case STRUCT_TYPE_7:
case STRUCT_TYPE_8:
case STRUCT_TYPE_9:
case STRUCT_TYPE_A:
case STRUCT_TYPE_B:
case STRUCT_TYPE_C:
case STRUCT_TYPE_D:
case STRUCT_TYPE_E:
break;
default:
2022-12-29 12:32:55 +00:00
CError_FATAL(618);
2022-10-25 19:30:28 +00:00
}
if (TYPE_STRUCT(ty)->name)
CError_BufferAppendString(eb, TYPE_STRUCT(ty)->name->name);
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
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_FLAGS_800)
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}");
}
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
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_FLAGS_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);
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
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);
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
}
break;
case TYPEFUNC:
if (TYPE_FUNC(ty)->flags & FUNC_FLAGS_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);
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
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) {
2023-01-14 13:20:48 +00:00
sprintf(buf, "%" PRId32, ty->size / TYPE_POINTER(ty)->target->size);
2022-10-25 19:30:28 +00:00
CError_BufferAppendString(eb, buf);
}
CError_BufferAppendChar(eb, ']');
ty = TYPE_POINTER(ty)->target;
}
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
case TYPETEMPLATE:
CError_BufferAppendQualifier(eb, qual);
CError_BufferAppendTemplDepType(eb, TYPE_TEMPLATE(ty));
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
case TYPETEMPLDEPEXPR:
CError_BufferAppendString(eb, "T");
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
case TYPEBITFIELD:
2023-01-14 13:20:48 +00:00
sprintf(buf, "bitfield:%" PRId32, TYPE_BITFIELD(ty)->unkB);
2022-10-25 19:30:28 +00:00
CError_BufferAppendString(eb, buf);
2023-01-10 11:05:21 +00:00
return;
2022-10-25 19:30:28 +00:00
default:
2022-12-29 12:32:55 +00:00
CError_FATAL(752);
2022-10-25 19:30:28 +00:00
}
}
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);
}
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_FLAGS_40)) {
CError_BufferAppendString(eb, "operator ");
CError_BufferAppendType(eb, tfunc->functype, tfunc->qual);
} else {
CError_BufferAppendString(eb, name->name);
}
} else {
CError_BufferAppendString(eb, opname);
}
}
}
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_FLAGS_100000))
CError_BufferAppendString(eb, "<...>");
CError_BufferAppendFuncArgs(eb, tfunc, 0);
} else {
CError_BufferAppendString(eb, "()");
}
}
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);
}
}
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;
2022-12-29 12:32:55 +00:00
CError_ASSERT(973, operatorName);
2022-10-25 19:30:28 +00:00
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;
char buf[128];
CWMessageRef myref;
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;
}
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, '\n');
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;
2023-01-10 11:05:21 +00:00
const char *p;
2022-10-25 19:30:28 +00:00
CError_BufferInit(&eb, buf, sizeof(buf));
2023-01-10 11:05:21 +00:00
p = format;
2022-10-25 19:30:28 +00:00
do {
2023-01-10 11:05:21 +00:00
switch (p[0]) {
2022-10-25 19:30:28 +00:00
case 0:
break;
case '%':
2023-01-10 11:05:21 +00:00
switch (p[1]) {
2022-10-25 19:30:28 +00:00
case 'n':
MWUnmangle(va_arg(list, const char *), unmangleBuf, sizeof(unmangleBuf));
CError_BufferAppendString(&eb, unmangleBuf);
2023-01-10 11:05:21 +00:00
p += 2;
2022-10-25 19:30:28 +00:00
continue;
case 'u':
CError_BufferAppendString(&eb, va_arg(list, const char *));
2023-01-10 11:05:21 +00:00
p += 2;
2022-10-25 19:30:28 +00:00
continue;
case 'o':
CError_AppendObjectName(&eb, va_arg(list, Object *));
2023-01-10 11:05:21 +00:00
p += 2;
2022-10-25 19:30:28 +00:00
continue;
case 'm':
CError_AppendMethodName(&eb, va_arg(list, ObjCMethod *));
2023-01-10 11:05:21 +00:00
p += 2;
2022-10-25 19:30:28 +00:00
continue;
case 't':
type = va_arg(list, Type *);
qual = va_arg(list, UInt32);
CError_BufferAppendType(&eb, type, qual);
2023-01-10 11:05:21 +00:00
p += 2;
2022-10-25 19:30:28 +00:00
continue;
case '%':
CError_BufferAppendChar(&eb, '%');
2023-01-10 11:05:21 +00:00
p += 2;
2022-10-25 19:30:28 +00:00
continue;
case 'i':
2023-01-14 13:20:48 +00:00
sprintf(unmangleBuf, "%" PRId32, va_arg(list, SInt32));
2022-10-25 19:30:28 +00:00
CError_BufferAppendString(&eb, unmangleBuf);
2023-01-10 11:05:21 +00:00
p += 2;
2022-10-25 19:30:28 +00:00
continue;
case 'f':
CError_BufferAppendString(&eb, CTool_GetPathName(va_arg(list, FSSpec *), &moddate)->name);
2023-01-10 11:05:21 +00:00
p += 2;
2022-10-25 19:30:28 +00:00
continue;
default:
2022-12-29 12:32:55 +00:00
CError_FATAL(1174);
2022-10-25 19:30:28 +00:00
}
break;
default:
2023-01-10 11:05:21 +00:00
CError_BufferAppendChar(&eb, *(p++));
2022-10-25 19:30:28 +00:00
continue;
}
break;
} while (1);
CError_BufferAppendTemplateStack(&eb);
CError_ErrorMessage(code, eb.start, flag1, flag2);
}
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;
2022-12-29 12:32:55 +00:00
CError_ASSERT(1268, args);
2022-10-25 19:30:28 +00:00
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_FLAGS_METHOD)
if (TYPE_FUNC(OBJECT(args->object)->type)->flags & FUNC_FLAGS_1000)
if (TYPE_METHOD(OBJECT(args->object)->type)->theclass->flags & CLASS_FLAGS_20)
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, ", ");
2023-01-10 11:05:21 +00:00
else
break;
2022-10-25 19:30:28 +00:00
}
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, '\n');
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;
2023-01-11 22:29:53 +00:00
CError_ErrorFuncCall(CErrorStr392, &first, argNodes);
2022-10-25 19:30:28 +00:00
}
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);
2023-01-11 22:29:53 +00:00
CError_GetErrorString(string, CErrorStr199);
2022-10-25 19:30:28 +00:00
CError_BufferInit(&eb, buf, sizeof(buf));
CError_BufferAppendString(&eb, string);
if (obj) {
CError_BufferAppendChar(&eb, '\n');
CError_BufferAppendChar(&eb, '\'');
CError_AppendObjectName(&eb, obj);
CError_BufferAppendChar(&eb, '\'');
}
while (olst) {
CError_BufferAppendChar(&eb, '\n');
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) {
2022-12-29 12:32:55 +00:00
Object *result = CClass_CheckPures(tclass);
2022-10-25 19:30:28 +00:00
if (!result)
2023-01-11 22:29:53 +00:00
CError_Error(CErrorStr372, tclass, 0);
2022-10-25 19:30:28 +00:00
else
2023-01-11 22:29:53 +00:00
CError_Error(CErrorStr194, result);
2022-10-25 19:30:28 +00:00
}
void CError_Warning(int code, ...) {
va_list va;
2023-01-10 11:05:21 +00:00
if (trychain || copts.supress_warnings)
2022-10-25 19:30:28 +00:00
return;
2023-01-10 11:05:21 +00:00
va_start(va, code);
CError_VAErrorMessage(code, va, 0, 1);
2022-10-25 19:30:28 +00:00
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);
}
2023-01-11 22:29:53 +00:00
void CError_ExpressionTooComplex(void) {
2022-10-25 19:30:28 +00:00
CompilerGetCString(6, string);
CError_ErrorMessage(10002, string, 1, 0);
longjmp(errorreturn, 1);
}
2023-01-11 22:29:53 +00:00
void CError_NoMem(void) {
2022-10-25 19:30:28 +00:00
cprep_nomem_exit = 1;
longjmp(errorreturn, 1);
}
2023-01-11 22:29:53 +00:00
void CError_UserBreak(void) {
2022-10-25 19:30:28 +00:00
CompilerGetCString(8, string);
longjmp(errorreturn, 1);
}
2023-01-11 22:29:53 +00:00
void CError_CannotOpen(void) {
2022-10-25 19:30:28 +00:00
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);
}
}