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/unsorted/CDecl.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/unsorted/CDecl.c')
-rw-r--r-- | compiler_and_linker/unsorted/CDecl.c | 4845 |
1 files changed, 0 insertions, 4845 deletions
diff --git a/compiler_and_linker/unsorted/CDecl.c b/compiler_and_linker/unsorted/CDecl.c deleted file mode 100644 index 43ca92e..0000000 --- a/compiler_and_linker/unsorted/CDecl.c +++ /dev/null @@ -1,4845 +0,0 @@ -#include "compiler/CDecl.h" -#include "compiler/CABI.h" -#include "compiler/CBrowse.h" -#include "compiler/CClass.h" -#include "compiler/CError.h" -#include "compiler/CException.h" -#include "compiler/CExpr.h" -#include "compiler/CFunc.h" -#include "compiler/CInit.h" -#include "compiler/CInline.h" -#include "compiler/CInt64.h" -#include "compiler/CMachine.h" -#include "compiler/CMangler.h" -#include "compiler/CObjC.h" -#include "compiler/CParser.h" -#include "compiler/CPrep.h" -#include "compiler/CPrepTokenizer.h" -#include "compiler/CSOM.h" -#include "compiler/CTemplateClass.h" -#include "compiler/CTemplateFunc.h" -#include "compiler/CTemplateNew.h" -#include "compiler/CTemplateTools.h" -#include "compiler/CompilerTools.h" -#include "compiler/objects.h" -#include "compiler/scopes.h" -#include "compiler/templates.h" -#include "compiler/tokens.h" - -AccessType global_access; -FileOffsetInfo member_fileoffset; - -// forward declarations -static void scandirectdecl1(DeclInfo *declinfo); - -Type *CDecl_NewStructType(SInt32 size, SInt16 align) { - TypeStruct *tstruct = galloc(sizeof(TypeStruct)); - memclrw(tstruct, sizeof(TypeStruct)); - - tstruct->type = TYPESTRUCT; - tstruct->size = size; - tstruct->align = align; - tstruct->stype = STRUCT_TYPE_STRUCT; - - return (Type *) tstruct; -} - -Type *CDecl_NewArrayType(Type *type, SInt32 size) { - TypePointer *tarray = galloc(sizeof(TypePointer)); - memclrw(tarray, sizeof(TypePointer)); - - tarray->type = TYPEARRAY; - tarray->size = size; - tarray->target = type; - tarray->qual = 0; - - return (Type *) tarray; -} - -Type *CDecl_NewPointerType(Type *type) { - TypePointer *tptr = galloc(sizeof(TypePointer)); - memclrw(tptr, sizeof(TypePointer)); - - tptr->type = TYPEPOINTER; - tptr->size = 4; - tptr->target = type; - - return (Type *) tptr; -} - -Type *CDecl_NewRefPointerType(Type *type) { - TypePointer *tptr = galloc(sizeof(TypePointer)); - memclrw(tptr, sizeof(TypePointer)); - - tptr->type = TYPEPOINTER; - tptr->size = 4; - tptr->target = type; - tptr->qual = Q_REFERENCE; - - return (Type *) tptr; -} - -Type *CDecl_NewTemplDepType(TypeTemplDepType tdt) { - TypeTemplDep *t = galloc(sizeof(TypeTemplDep)); - memclrw(t, sizeof(TypeTemplDep)); - - t->type = TYPETEMPLATE; - t->size = 1; - t->dtype = tdt; - - return (Type *) t; -} - -void CDecl_SetResultReg(TypeFunc *tfunc) { -} - -static void CDecl_SetFuncResultReg(TypeFunc *tfunc) { -} - -void CDecl_SetFuncFlags(TypeFunc *tfunc, UInt32 flags) { - CDecl_SetResultReg(tfunc); -} - -static void CDecl_ParseCPPFuncDecl(TypeFunc *tfunc) { - for (;;) { - if (tk == TK_CONST) { - if (tfunc->flags & FUNC_CONST) - CError_Warning(CErrorStr313, "const"); - tfunc->flags |= FUNC_CONST; - tk = lex(); - } else if (tk == TK_VOLATILE) { - if (tfunc->flags & FUNC_VOLATILE) - CError_Warning(CErrorStr313, "volatile"); - tfunc->flags |= FUNC_VOLATILE; - tk = lex(); - } else { - break; - } - } - - if (tk == TK_THROW) - CExcept_ScanExceptionSpecification(tfunc); -} - -void CDecl_NewConvFuncType(DeclInfo *declinfo) { - TypeFunc *tfunc; - - if (tk != '(') - CError_Error(CErrorStr114); - else - tk = lex(); - - if (tk == TK_VOID) - tk = lex(); - - if (tk != ')') - CError_Error(CErrorStr115); - else - tk = lex(); - - tfunc = galloc(sizeof(TypeFunc)); - memclrw(tfunc, sizeof(TypeFunc)); - declinfo->name = CMangler_ConversionFuncName(declinfo->thetype, declinfo->qual); - tfunc->type = TYPEFUNC; - tfunc->functype = declinfo->thetype; - tfunc->qual = declinfo->qual & (Q_CONST | Q_VOLATILE); - tfunc->flags = FUNC_CONVERSION; - declinfo->x49 = 0; - CDecl_SetFuncFlags(tfunc, 1); - CDecl_ParseCPPFuncDecl(tfunc); - - declinfo->thetype = (Type *) tfunc; - declinfo->qual &= ~(Q_CONST | Q_VOLATILE); - declinfo->storageclass = 0; -} - -void CDecl_CompleteType(Type *type) { - switch (type->type) { - case TYPEPOINTER: - if ((TYPE_POINTER(type)->qual & Q_REFERENCE) && IS_TYPE_CLASS(TYPE_POINTER(type)->target)) { - type = TYPE_POINTER(type)->target; - break; - } - return; - case TYPEARRAY: - do { - type = TYPE_POINTER(type)->target; - } while (IS_TYPE_ARRAY(type)); - if (IS_TYPE_CLASS(type)) - break; - return; - case TYPECLASS: - break; - default: - return; - } - - if ((TYPE_CLASS(type)->flags & (CLASS_COMPLETED | CLASS_IS_TEMPL_INST)) == CLASS_IS_TEMPL_INST) - CTempl_InstantiateTemplateClass(TYPE_CLASS(type)); -} - -Boolean IsCompleteType(Type *type) { - switch (type->type) { - case TYPEVOID: - CError_Error(CErrorStr126); - return 0; - case TYPEFUNC: - CError_Error(CErrorStr146); - return 0; - case TYPESTRUCT: - if (!type->size) { - CError_Error(CErrorStr136, type, 0); - return 0; - } - return 1; - case TYPECLASS: - if ( - !(TYPE_CLASS(type)->flags & CLASS_COMPLETED) && - ( - !(TYPE_CLASS(type)->flags & CLASS_IS_TEMPL_INST) || - !CTempl_InstantiateTemplateClass(TYPE_CLASS(type)) - ) - ) - { - CError_Error(CErrorStr136, type, 0); - return 0; - } - return 1; - default: - if (!type->size) { - CError_Error(CErrorStr145); - return 0; - } - return 1; - } -} - -Boolean CanAllocObject(Type *type) { - switch (type->type) { - case TYPEVOID: - CError_Error(CErrorStr126); - return 0; - case TYPEFUNC: - CError_Error(CErrorStr146); - return 0; - case TYPECLASS: - if (TYPE_CLASS(type)->flags & CLASS_ABSTRACT) { - CError_AbstractClassError(TYPE_CLASS(type)); - return 0; - } - default: - return 1; - } -} - -Boolean CanCreateObject(Type *type) { - if (!CanAllocObject(type)) - return 0; - - if (IS_TYPE_CLASS(type)) { - if (TYPE_CLASS(type)->flags & CLASS_HANDLEOBJECT) { - CError_Error(CErrorStr191); - return 0; - } - if (TYPE_CLASS(type)->objcinfo) { - CError_Error(CErrorStr307); - return 0; - } - } - - return 1; -} - -static Boolean CanCreateHandleMemberObject(Type *type) { - while (IS_TYPE_ARRAY(type)) - type = TYPE_POINTER(type)->target; - - if (!CanCreateObject(type)) - return 0; - - if (IS_TYPE_CLASS(type)) { - if (CClass_Destructor(TYPE_CLASS(type)) || CClass_Constructor(TYPE_CLASS(type))) { - CError_Error(CErrorStr191); - return 0; - } - } - - return 1; -} - -void makethetypepointer(DeclInfo *declinfo, UInt32 qual) { - declinfo->thetype = CDecl_NewPointerType(declinfo->thetype); - TYPE_POINTER(declinfo->thetype)->qual = qual; -} - -void CDecl_AddThisPointerArgument(TypeFunc *tfunc, TypeClass *tclass) { - Type *ptype; - FuncArg *arg; - - ptype = CDecl_NewPointerType(!tclass->sominfo ? (Type *) tclass : &stvoid); - TYPE_POINTER(ptype)->qual = Q_CONST; - - arg = CParser_NewFuncArg(); - arg->name = this_name_node; - arg->type = ptype; - if (tfunc->flags & FUNC_CONST) - arg->qual |= Q_CONST; - if (tfunc->flags & FUNC_VOLATILE) - arg->qual |= Q_VOLATILE; - arg->next = tfunc->args; - tfunc->args = arg; -} - -void CDecl_MakePTMFuncType(TypeFunc *tfunc) { - Type *cvoidp; - FuncArg *arg1; - FuncArg *arg2; - - cvoidp = CDecl_NewPointerType(&stvoid); - TYPE_POINTER(cvoidp)->qual = Q_CONST; - - arg1 = CParser_NewFuncArg(); - arg1->name = this_name_node; - arg1->type = cvoidp; - if (tfunc->flags & FUNC_CONST) - arg1->qual |= Q_CONST; - if (tfunc->flags & FUNC_VOLATILE) - arg1->qual |= Q_VOLATILE; - - arg2 = CParser_NewFuncArg(); - arg2->name = this_name_node; - arg2->type = cvoidp; - arg2->qual = Q_CONST; - - arg1->next = tfunc->args; - arg2->next = arg1; - tfunc->args = arg2; - tfunc->flags |= FUNC_FLAGS_80; -} - -void CDecl_AddArgument(TypeFunc *tfunc, Type *argtype) { - FuncArg *arg = CParser_NewFuncArg(); - arg->type = argtype; - - arg->next = tfunc->args; - tfunc->args = arg; - - if (arg->next && arg->next->type == &stvoid) - arg->next = NULL; -} - -Boolean CDecl_CheckArrayIntegr(Type *type) { - if (!IsCompleteType(type)) - return 0; - - if (IS_TYPE_CLASS(type) && TYPE_CLASS(type)->sominfo) { - CError_Error(CErrorStr289); - return 0; - } - - if (IS_TYPE_REFERENCE(type)) { - CError_Error(CErrorStr196); - return 0; - } - - return CanCreateObject(type); -} - -static Boolean checkfuncintegr(Type *type) { - if (IS_TYPE_VOID(type)) - return 1; - - if (IS_TYPE_CLASS(type) && TYPE_CLASS(type)->sominfo) { - CError_Error(CErrorStr283); - return 0; - } - - return CanCreateObject(type); -} - -void CDecl_ParseDirectFuncDecl(DeclInfo *declinfo) { - FuncArg *list; - TypeFunc *tfunc; - - if (tk == ')') { - if (copts.cplusplus) - list = NULL; - else - list = &oldstyle; - tk = lex(); - } else { - list = parameter_type_list(declinfo); - if (tk != ')') - CError_ErrorSkip(CErrorStr115); - else - tk = lex(); - } - - tfunc = galloc(sizeof(TypeFunc)); - memclrw(tfunc, sizeof(TypeFunc)); - tfunc->type = TYPEFUNC; - tfunc->args = list; - if (declinfo->qual & Q_PASCAL) { - declinfo->qual &= ~Q_PASCAL; - tfunc->flags = FUNC_PASCAL; - } - - if (copts.cplusplus) { - CDecl_ParseCPPFuncDecl(tfunc); - if (declinfo->storageclass == TK_TYPEDEF && tfunc->exspecs) - CError_Error(CErrorStr264); - } - - scandirectdecl1(declinfo); - if (!checkfuncintegr(declinfo->thetype)) - declinfo->thetype = &stvoid; - - tfunc->functype = declinfo->thetype; - tfunc->qual = declinfo->qual & (Q_CONST | Q_VOLATILE); - declinfo->thetype = (Type *) tfunc; - declinfo->qual &= ~(Q_CONST | Q_VOLATILE); - declinfo->x49 = 0; -} - -static void scandirectdecl1(DeclInfo *declinfo) { - Boolean flag; - CInt64 len; - ENode *expr; - TypeTemplDep *ttempl; - - flag = 0; - if (tk == '[') { - if ((tk = lex()) == ']') { - len = cint64_zero; - tk = lex(); - flag = 1; - } else { - if (!declinfo->x46 || declinfo->x47) { - expr = CExpr_IntegralConstOrDepExpr(); - if (!ENODE_IS(expr, EINTCONST)) { - if (tk != ']') - CError_ErrorSkip(CErrorStr125); - else - tk = lex(); - declinfo->x47 = 1; - scandirectdecl1(declinfo); - if (!CDecl_CheckArrayIntegr(declinfo->thetype)) - declinfo->thetype = (Type *) &stsignedchar; - ttempl = (TypeTemplDep *) CDecl_NewTemplDepType(TEMPLDEP_ARRAY); - ttempl->u.array.type = declinfo->thetype; - ttempl->u.array.index = CInline_CopyExpression(expr, CopyMode1); - declinfo->thetype = (Type *) ttempl; - return; - } - len = expr->data.intval; - if (CInt64_IsNegative(&len)) { - CError_Error(CErrorStr124); - len = cint64_one; - } else if (CInt64_IsZero(&len)) { - if (!copts.ANSIstrict && declinfo->x50) { - flag = 1; - } else { - CError_Error(CErrorStr124); - len = cint64_one; - } - } - } else { - len = cint64_one; - expr = expression(); - if (IS_TYPE_INT(expr->rtype)) { - if (!ENODE_IS(expr, EINTCONST)) - declinfo->x24 = expr; - else - len = expr->data.intval; - } else { - CError_Error(CErrorStr124); - } - } - - if (tk != ']') - CError_ErrorSkip(CErrorStr125); - else - tk = lex(); - } - - declinfo->x47 = 1; - scandirectdecl1(declinfo); - - if (!flag && !CDecl_CheckArrayIntegr(declinfo->thetype)) - declinfo->thetype = (Type *) &stsignedchar; - - if (!declinfo->thetype->size && CTemplTool_IsTemplateArgumentDependentType(declinfo->thetype)) { - ttempl = (TypeTemplDep *) CDecl_NewTemplDepType(TEMPLDEP_ARRAY); - ttempl->u.array.type = declinfo->thetype; - ttempl->u.array.index = CInline_CopyExpression(intconstnode((Type *) &stsignedint, CInt64_GetULong(&len)), CopyMode1); - declinfo->thetype = (Type *) ttempl; - } else { - declinfo->thetype = CDecl_NewArrayType(declinfo->thetype, declinfo->thetype->size * CInt64_GetULong(&len)); - } - } else if (tk == '(') { - if (!copts.cplusplus || !declinfo->name || IS_TYPE_VOID(declinfo->thetype) || CParser_TryParamList(!IS_TYPE_CLASS(declinfo->thetype))) { - tk = lex(); - CDecl_ParseDirectFuncDecl(declinfo); - } - } -} - -static void substitute_type(Type *type1, Type *type2) { - SInt32 oldsize; - - while (1) { - switch (type1->type) { - case TYPEPOINTER: - if (TYPE_POINTER(type1)->target == &stillegal) { - TYPE_POINTER(type1)->target = type2; - type1->size = 4; - return; - } - type1 = TYPE_POINTER(type1)->target; - break; - case TYPEMEMBERPOINTER: - if (TYPE_MEMBER_POINTER(type1)->ty1 == &stillegal) { - TYPE_MEMBER_POINTER(type1)->ty1 = type2; - if (IS_TYPE_FUNC(type2)) { - CDecl_MakePTMFuncType(TYPE_FUNC(type2)); - type1->size = 12; - } else { - type1->size = 4; - } - return; - } - type1 = TYPE_MEMBER_POINTER(type1)->ty1; - break; - case TYPEARRAY: - if (TYPE_POINTER(type1)->target == &stillegal) { - if (!CDecl_CheckArrayIntegr(type2)) - type2 = (Type *) &stsignedchar; - type1->size *= type2->size; - TYPE_POINTER(type1)->target = type2; - return; - } - oldsize = TYPE_POINTER(type1)->target->size; - substitute_type(TYPE_POINTER(type1)->target, type2); - if (oldsize != TYPE_POINTER(type1)->target->size && oldsize != 0) - type1->size = TYPE_POINTER(type1)->target->size * (type1->size / oldsize); - return; - case TYPEFUNC: - if (TYPE_FUNC(type1)->functype == &stillegal) { - if (!checkfuncintegr(type2)) - type2 = &stvoid; - TYPE_FUNC(type1)->functype = type2; - CDecl_SetFuncResultReg((TypeFunc *) type1); - return; - } - type1 = TYPE_FUNC(type1)->functype; - break; - case TYPETEMPLATE: - if (TYPE_TEMPLATE(type1)->dtype == TEMPLDEP_ARRAY) { - if (TYPE_TEMPLATE(type1)->u.array.type == &stillegal) { - if (!CDecl_CheckArrayIntegr(type2)) - type2 = (Type *) &stsignedchar; - TYPE_TEMPLATE(type1)->u.array.type = type2; - return; - } - type1 = TYPE_TEMPLATE(type1)->u.array.type; - } else { - CError_Error(CErrorStr146); - return; - } - break; - default: - CError_Error(CErrorStr121); - return; - } - } -} - -static void scandecl(DeclInfo *declinfo) { - Type *oldtype; - Type *newtype; - - oldtype = declinfo->thetype; - declinfo->thetype = &stillegal; - scandeclarator(declinfo); - - if (tk != ')') - CError_ErrorSkip(CErrorStr115); - else - tk = lex(); - - newtype = declinfo->thetype; - if (newtype == &stillegal) { - declinfo->thetype = oldtype; - scandirectdecl1(declinfo); - } else { - declinfo->thetype = oldtype; - scandirectdecl1(declinfo); - substitute_type(newtype, declinfo->thetype); - declinfo->thetype = newtype; - } -} - -static Boolean CDecl_ParseOperatorDecl(DeclInfo *declinfo) { - if (declinfo->operator_token) { - CError_Error(CErrorStr121); - return 0; - } - - declinfo->operator_token = 0; - if (!CParser_ParseOperatorName(&declinfo->operator_token, declinfo->x4A && cscope_current->theclass, 0)) - return 0; - - if (!declinfo->operator_token) { - conversion_type_name(declinfo); - tkidentifier = CMangler_ConversionFuncName(declinfo->thetype, declinfo->qual); - declinfo->x54 = 1; - } - return 1; -} - -static Boolean CDecl_IsEnumClassTypeOrRef(Type *type) { - if (IS_TYPE_CLASS(type) || IS_TYPE_ENUM(type)) - return 1; - if (!IS_TYPE_REFERENCE(type)) - return 0; - type = TYPE_POINTER(type)->target; - return IS_TYPE_CLASS(type) || IS_TYPE_ENUM(type); -} - -static Boolean CDecl_CheckOperatorType(DeclInfo *declinfo, Boolean flag) { - FuncArg *args; - FuncArg *secondarg; - Type *functype; - short argCount; - Boolean isMethod; - - if (!IS_TYPE_FUNC(declinfo->thetype)) { - CError_Error(CErrorStr193); - return 0; - } - - functype = TYPE_FUNC(declinfo->thetype)->functype; - args = TYPE_FUNC(declinfo->thetype)->args; - if (args) { - if (args != &elipsis && args != &oldstyle) { - argCount = 1; - if (args->dexpr) { - switch (declinfo->operator_token) { - case TK_NEW: - case TK_DELETE: - case TK_NEW_ARRAY: - case TK_DELETE_ARRAY: - break; - default: - CError_Error(CErrorStr205); - } - } - - secondarg = args->next; - if (secondarg) { - argCount = ((secondarg != &elipsis && !secondarg->next) != 0) ? 2 : 3; - if (secondarg->dexpr) { - switch (declinfo->operator_token) { - case '(': - case TK_NEW: - case TK_DELETE: - case TK_NEW_ARRAY: - case TK_DELETE_ARRAY: - break; - default: - CError_Error(CErrorStr205); - } - } - } - } else { - argCount = 3; - } - } else { - CError_Error(CErrorStr193); - return 0; - } - - isMethod = flag && - IS_TYPEFUNC_METHOD(TYPE_FUNC(declinfo->thetype)) && - !TYPE_METHOD(declinfo->thetype)->is_static; - - switch (declinfo->operator_token) { - case TK_NEW: - case TK_NEW_ARRAY: - if (isMethod || !is_typesame(functype, TYPE(&void_ptr)) || argCount < 1 || args->type != CABI_GetSizeTType()) { - CError_Error(CErrorStr193); - return 0; - } - return 1; - case TK_DELETE: - case TK_DELETE_ARRAY: - if (isMethod || !IS_TYPE_VOID(functype) || argCount < 1 || !is_typesame(args->type, TYPE(&void_ptr))) { - CError_Error(CErrorStr193); - return 0; - } - return 1; - case '=': - if (!isMethod) { - CError_Error(CErrorStr193); - return 0; - } - break; - case '(': - if (!isMethod) { - CError_Error(CErrorStr193); - return 0; - } - return 1; - case '[': - if (!isMethod) { - CError_Error(CErrorStr193); - return 0; - } - break; - case TK_ARROW: - if (argCount != 1 || isMethod == 0) { - CError_Error(CErrorStr193); - return 0; - } - return 1; - case TK_INCREMENT: - case TK_DECREMENT: - if (argCount == 2 && secondarg->type != TYPE(&stsignedint)) { - CError_Error(CErrorStr193); - return 0; - } - break; - } - - if (flag && !isMethod) { - CError_Error(CErrorStr193); - return 0; - } - - switch (declinfo->operator_token) { - case '&': - case '*': - case '+': - case '-': - case TK_INCREMENT: - case TK_DECREMENT: - if (argCount != 1) - goto whatever; - case '!': - case '~': - if (argCount == 1) { - if (flag || CDecl_IsEnumClassTypeOrRef(args->type)) - return 1; - } - break; - case '%': - case ',': - case '/': - case '<': - case '=': - case '>': - case '[': - case '^': - case '|': - case TK_MULT_ASSIGN: - case TK_DIV_ASSIGN: - case TK_MOD_ASSIGN: - case TK_ADD_ASSIGN: - case TK_SUB_ASSIGN: - case TK_SHL_ASSIGN: - case TK_SHR_ASSIGN: - case TK_AND_ASSIGN: - case TK_XOR_ASSIGN: - case TK_OR_ASSIGN: - case TK_LOGICAL_OR: - case TK_LOGICAL_AND: - case TK_LOGICAL_EQ: - case TK_LOGICAL_NE: - case TK_LESS_EQUAL: - case TK_GREATER_EQUAL: - case TK_SHL: - case TK_SHR: - case TK_ARROW: - case TK_DOT_STAR: - case TK_ARROW_STAR: - whatever: - if (argCount == 2) { - if (flag || CDecl_IsEnumClassTypeOrRef(args->type) || CDecl_IsEnumClassTypeOrRef(secondarg->type)) - return 1; - } - break; - } - - CError_Error(CErrorStr193); - return 0; -} - -static void scandirectdeclarator(DeclInfo *declinfo, NameSpace *nspace) { - HashNameNode *saveident; - CScopeSave scopesave; - Boolean flag; - - if (nspace) - CScope_SetNameSpaceScope(nspace, &scopesave); - - if (tk == '(') { - if ((tk = lex()) == ')') { - if (declinfo->x55) { - CDecl_ParseDirectFuncDecl(declinfo); - if (nspace) - CScope_RestoreScope(&scopesave); - return; - } else { - CError_Error(CErrorStr121); - if (nspace) - CScope_RestoreScope(&scopesave); - return; - } - } - - if (!(tk >= TK_AUTO && tk <= TK_BYREF)) { - if (!(tk == TK_IDENTIFIER && CScope_PossibleTypeName(tkidentifier))) { - scandecl(declinfo); - if (nspace) - CScope_RestoreScope(&scopesave); - return; - } else { - saveident = tkidentifier; - switch (lookahead()) { - case ')': - case ',': - break; - default: - tkidentifier = saveident; - scandecl(declinfo); - if (nspace) - CScope_RestoreScope(&scopesave); - return; - } - } - } - - if (declinfo->name) - CError_Error(CErrorStr121); - - CDecl_ParseDirectFuncDecl(declinfo); - if (nspace) - CScope_RestoreScope(&scopesave); - return; - } - - if (nspace) { - if (tk == TK_OPERATOR) { - if (!CDecl_ParseOperatorDecl(declinfo)) { - CScope_RestoreScope(&scopesave); - return; - } - - if (declinfo->x54) { - declinfo->nspace = nspace; - declinfo->name = tkidentifier; - if (nspace) - CScope_RestoreScope(&scopesave); - - if (tk == '(') { - tk = lex(); - CDecl_ParseDirectFuncDecl(declinfo); - if (IS_TYPE_FUNC(declinfo->thetype)) - TYPE_FUNC(declinfo->thetype)->flags |= FUNC_CONVERSION; - else - CError_Error(CErrorStr121); - } else { - CError_Error(CErrorStr114); - } - return; - } - - flag = 1; - } else if (tk != TK_IDENTIFIER) { - CError_Error(CErrorStr107); - CScope_RestoreScope(&scopesave); - return; - } else { - flag = 0; - } - - if (declinfo->name) { - CError_Error(CErrorStr121); - CScope_RestoreScope(&scopesave); - return; - } - - declinfo->nspace = nspace; - declinfo->name = tkidentifier; - if (!flag) - tk = lex(); - } else if (tk == TK_IDENTIFIER) { - if (declinfo->name) - CError_Error(CErrorStr121); - declinfo->name = tkidentifier; - tk = lex(); - } else if (tk == TK_OPERATOR) { - if (!CDecl_ParseOperatorDecl(declinfo)) - return; - declinfo->name = tkidentifier; - } - - if (tk == '<' && declinfo->x51) { - declinfo->expltargs = CTempl_ParseUncheckTemplArgs(NULL, 0); - declinfo->has_expltargs = 1; - declinfo->x51 = 0; - tk = lex(); - } - - scandirectdecl1(declinfo); - - if (nspace) - CScope_RestoreScope(&scopesave); -} - -void makememberpointertype(DeclInfo *declinfo, TypeClass *tclass, UInt32 qual) { - TypeMemberPointer *tmemp; - TypeFunc *tfunc; - - if (tclass->flags & CLASS_HANDLEOBJECT) { - CError_Error(CErrorStr191); - declinfo->thetype = (Type *) &stsignedint; - return; - } - if (tclass->sominfo) { - CError_Error(CErrorStr290); - declinfo->thetype = (Type *) &stsignedint; - return; - } - - tmemp = galloc(sizeof(TypeMemberPointer)); - memclrw(tmemp, sizeof(TypeMemberPointer)); - tmemp->type = TYPEMEMBERPOINTER; - tmemp->ty2 = (Type *) tclass; - tmemp->qual = qual; - - if (IS_TYPE_FUNC(declinfo->thetype)) { - tfunc = galloc(sizeof(TypeFunc)); - *tfunc = *TYPE_FUNC(declinfo->thetype); - tmemp->ty1 = (Type *) tfunc; - tmemp->size = 12; - CDecl_MakePTMFuncType(tfunc); - } else { - tmemp->size = 4; - tmemp->ty1 = declinfo->thetype; - } - declinfo->thetype = (Type *) tmemp; -} - -void CDecl_ScanPointer(DeclInfo *declinfo, NameSpace *nspace, Boolean flag) { - NameResult pr; - UInt32 qual; - - while (1) { - qual = (tk == '&') ? Q_REFERENCE : 0; - - for (tk = lex(); ; tk = lex()) { - switch (tk) { - case TK_CONST: - if (qual & Q_CONST) - CError_Error(CErrorStr121); - qual |= Q_CONST; - continue; - case TK_VOLATILE: - if (qual & Q_VOLATILE) - CError_Error(CErrorStr121); - qual |= Q_VOLATILE; - continue; - case TK_RESTRICT: - if (qual & Q_RESTRICT) - CError_Error(CErrorStr121); - qual |= Q_RESTRICT; - continue; - default: - break; - } - break; - } - - if (IS_TYPE_REFERENCE(declinfo->thetype) || ((qual & Q_REFERENCE) && IS_TYPE_VOID(declinfo->thetype))) { - CError_Error(CErrorStr196); - return; - } - - if (nspace) { - makememberpointertype(declinfo, nspace->theclass, qual); - nspace = NULL; - } else { - makethetypepointer(declinfo, qual); - } - - switch (tk) { - case '*': - continue; - case '&': - if (!copts.cplusplus) { - if (flag) - scandirectdeclarator(declinfo, NULL); - return; - } - continue; - case TK_IDENTIFIER: - if (!copts.cplusplus) - break; - if (copts.cpp_extensions && cscope_current->theclass && cscope_current->theclass->classname == tkidentifier && lookahead() == TK_COLON_COLON) { - tk = lex(); - tk = lex(); - break; - } - case TK_COLON_COLON: - if (CScope_ParseQualifiedNameSpace(&pr, 1, 0)) { - if ((nspace = pr.nspace_0)) { - if (nspace->theclass && tk == '*') - continue; - } else { - if (pr.type && IS_TYPE_TEMPLATE(pr.type) && declinfo->x30) { - if (CTempl_IsQualifiedMember(declinfo, pr.type, &nspace)) - scandirectdeclarator(declinfo, nspace); - else - declinfo->x20 = pr.type; - return; - } - CError_Error(CErrorStr121); - } - } - break; - } - break; - } - - if (flag) - scandirectdeclarator(declinfo, nspace); -} - -static void CDecl_TemplatePTM(DeclInfo *declinfo, Type *type) { - TypeMemberPointer *tmemp = galloc(sizeof(TypeMemberPointer)); - tmemp->type = TYPEMEMBERPOINTER; - if (IS_TYPE_FUNC(declinfo->thetype)) { - CDecl_MakePTMFuncType((TypeFunc *) declinfo->thetype); - tmemp->size = 12; - } else { - tmemp->size = 4; - } - - tmemp->ty1 = declinfo->thetype; - tmemp->ty2 = type; - tmemp->qual = 0; - declinfo->thetype = (Type *) tmemp; -} - -void scandeclarator(DeclInfo *declinfo) { - NameResult pr; - NameSpace *nspace; - - switch (tk) { - case '&': - if (!copts.cplusplus) - break; - case '*': - CDecl_ScanPointer(declinfo, NULL, 1); - if (tk == TK_UU_ATTRIBUTE_UU) - CParser_ParseAttribute(NULL, declinfo); - return; - case TK_IDENTIFIER: - if (!copts.cplusplus) - break; - case TK_COLON_COLON: - if (CScope_ParseQualifiedNameSpace(&pr, 1, 0)) { - nspace = pr.nspace_0; - if (nspace) { - if (nspace->theclass && tk == '*') - CDecl_ScanPointer(declinfo, nspace, 1); - else - scandirectdeclarator(declinfo, nspace); - return; - } - if (pr.type && IS_TYPE_TEMPLATE(pr.type)) { - if (declinfo->x30 && CTempl_IsQualifiedMember(declinfo, pr.type, &nspace)) { - scandirectdeclarator(declinfo, nspace); - return; - } else if (declinfo->x30 && tk == TK_OPERATOR) { - declinfo->x20 = pr.type; - return; - } else if ((tk = lex()) == TK_COLON_COLON && (tk = lex()) == '*') { - CDecl_TemplatePTM(declinfo, pr.type); - tk = lex(); - break; - } else if (declinfo->x30) { - declinfo->x20 = pr.type; - return; - } - } - CError_Error(CErrorStr121); - } - break; - } - - scandirectdeclarator(declinfo, NULL); - if (tk == TK_UU_ATTRIBUTE_UU) - CParser_ParseAttribute(NULL, declinfo); -} - -void conversion_type_name(DeclInfo *declinfo) { - NameResult pr; - DeclInfo subdeclinfo; - - memclrw(&subdeclinfo, sizeof(DeclInfo)); - CParser_GetDeclSpecs(&subdeclinfo, 0); - - switch (tk) { - case '&': - case '*': - CDecl_ScanPointer(&subdeclinfo, NULL, 0); - break; - case TK_IDENTIFIER: - case TK_COLON_COLON: - if (CScope_ParseQualifiedNameSpace(&pr, 0, 0)) { - if (pr.nspace_0 && pr.nspace_0->theclass && tk == '*') - CDecl_ScanPointer(&subdeclinfo, pr.nspace_0, 0); - else - CError_Error(CErrorStr121); - } - break; - } - - declinfo->name = subdeclinfo.name; - declinfo->thetype = subdeclinfo.thetype; - declinfo->qual |= subdeclinfo.qual; -} - -static void scaninlinefunc(Object *obj) { - short array[256]; - short r29; - CInt64 val; - - if (tk == '{') { - tk = lex(); - r29 = 0; - while (1) { - if (r29 >= 256) { - CError_Error(CErrorStr127); - r29 = 255; - } - val = CExpr_IntegralConstExpr(); - array[r29++] = CInt64_GetULong(&val); - if (tk != '}') { - if (tk != ',') - CError_Error(CErrorStr116); - tk = lex(); - } else { - tk = lex(); - break; - } - } - } else { - val = CExpr_IntegralConstExpr(); - array[0] = CInt64_GetULong(&val); - r29 = 1; - } - - obj->datatype = DINLINEFUNC; - obj->u.ifunc.size = r29 * 2; - obj->u.ifunc.data = galloc(obj->u.ifunc.size); - obj->u.ifunc.xrefs = NULL; - memcpy(obj->u.ifunc.data, array, obj->u.ifunc.size); - - if (tk != ';') - CError_Error(CErrorStr123); -} - -typedef enum { - OverloadMode0, - OverloadMode1, - OverloadMode2, - OverloadMode3 -} OverloadMode; - -static Object *CDecl_OverloadFunctionObject(NameSpaceObjectList *list, DeclInfo *declinfo, Boolean *outflag, OverloadMode mode, Boolean flag2) { - TypeFunc *scanfunc; - NameSpaceObjectList *scan; - TypeFunc *tfunc; - FuncArg *args; - FuncArg *scanargs; - Object *obj; - Boolean r24; - short compareresult; - - if (outflag) - *outflag = 0; - - tfunc = (TypeFunc *) declinfo->thetype; - args = tfunc->args; - r24 = 0; - for (scan = list; scan; scan = scan->next) { - obj = OBJECT(scan->object); - if (obj->otype != OT_OBJECT) - continue; - - scanfunc = TYPE_FUNC(obj->type); - if (!IS_TYPE_FUNC(scanfunc)) - continue; - - scanargs = scanfunc->args; - if (scanfunc->flags & FUNC_IS_TEMPL) - r24 = 1; - - if (IS_TYPEFUNC_METHOD(scanfunc)) { - switch (mode) { - case OverloadMode0: - CError_Error(CErrorStr197); - break; - case OverloadMode1: - if (!TYPE_METHOD(scanfunc)->is_static) - continue; - break; - case OverloadMode2: - if (TYPE_METHOD(scanfunc)->is_static) - continue; - break; - case OverloadMode3: - if (!TYPE_METHOD(scanfunc)->is_static) { - if (scanargs->qual & Q_CV) - continue; - scanargs = scanargs->next; - } - break; - } - } else { - if (mode) - CError_Error(CErrorStr197); - } - - compareresult = CParser_CompareArgLists(args, scanargs); - if (compareresult == 1) { - if (scanfunc->flags & FUNC_CONVERSION) { - if (!(tfunc->flags & FUNC_CONVERSION)) { - CError_Error(CErrorStr197); - break; - } - if (!is_typesame(tfunc->functype, scanfunc->functype)) - continue; - if ((tfunc->qual & Q_CV) != (scanfunc->qual & Q_CV)) - continue; - if ((tfunc->flags & FUNC_CALL_CONV_MASK) != (scanfunc->flags & FUNC_CALL_CONV_MASK)) { - CError_Error(CErrorStr197); - break; - } - if (tfunc->exspecs || scanfunc->exspecs) - CExcept_CompareSpecifications(tfunc->exspecs, scanfunc->exspecs); - return obj; - } - - if (tfunc->flags & FUNC_CONVERSION) { - CError_Error(CErrorStr197); - break; - } - - if ( - !is_typesame(tfunc->functype, scanfunc->functype) || - ((tfunc->qual & (Q_CONST | Q_PASCAL)) != (scanfunc->qual & (Q_CONST | Q_PASCAL))) || - ((tfunc->flags & FUNC_CALL_CONV_MASK) != (scanfunc->flags & FUNC_CALL_CONV_MASK)) - ) - { - CError_Error(CErrorStr197); - break; - } - - if (tfunc->exspecs || scanfunc->exspecs) { - if (obj->name != newp_fobj->name && obj->name != newa_fobj->name && obj->name != delp_fobj->name && obj->name != dela_fobj->name) - CExcept_CompareSpecifications(tfunc->exspecs, scanfunc->exspecs); - } - - return obj; - } else if (compareresult == 2) { - CError_Error(CErrorStr197); - break; - } - } - - if (r24 && (flag2 || declinfo->x3C)) { - if ((obj = CTempl_TemplateFunctionCheck(declinfo, list))) - return obj; - } - - if (!outflag) { - CError_Error(CErrorStr197); - return NULL; - } - - if (declinfo->nspace) - CError_Error(CErrorStr336); - - *outflag = 1; - obj = CParser_NewFunctionObject(declinfo); - CheckDefaultArgs(TYPE_FUNC(obj->type)->args); - - if (tfunc->flags & FUNC_PASCAL) { - for (scan = list; scan; scan = scan->next) { - if (scan->object->otype == OT_OBJECT && IS_TYPE_FUNC(OBJECT(scan->object)->type)) { - if (TYPE_FUNC(OBJECT(scan->object)->type)->flags & FUNC_PASCAL) - CError_Error(CErrorStr226); - } - } - } - - if (copts.cplusplus && declinfo->is_extern_c) { - for (scan = list; scan; scan = scan->next) { - if (scan->object->otype == OT_OBJECT && !(OBJECT(scan->object)->qual & Q_MANGLE_NAME)) - CError_Error(CErrorStr197); - } - } - - CScope_AddObject(cscope_current, declinfo->name, OBJ_BASE(obj)); - if (cscope_current->theclass && (cscope_current->theclass->flags & CLASS_IS_TEMPL) && - CTemplTool_IsTemplateArgumentDependentType(declinfo->thetype)) - CTemplClass_RegisterObjectDef(TEMPL_CLASS(cscope_current->theclass), OBJ_BASE(obj)); - - return obj; -} - -void MergeDefaultArgs(FuncArg *a, FuncArg *b) { - FuncArg *scan_a; - FuncArg *scan_b; - - if (a == &oldstyle || b == &oldstyle) - return; - - scan_a = a; - scan_b = b; - while (scan_a && scan_b) { - if (scan_a->dexpr) { - while (scan_b) { - if (scan_b->dexpr) { - while (a) { - a->dexpr = NULL; - a = a->next; - } - while (b) { - b->dexpr = NULL; - b = b->next; - } - CError_Error(CErrorStr205); - return; - } - scan_b = scan_b->next; - } - break; - } else if (scan_b->dexpr) { - do { - scan_a = scan_a->next; - scan_b = scan_b->next; - if (!scan_a) goto secondpart; - if (scan_a == &elipsis) goto secondpart; - if (scan_a->dexpr && scan_b->dexpr) break; - } while (scan_a->dexpr || scan_b->dexpr); - - while (a) { - a->dexpr = NULL; - a = a->next; - } - while (b) { - b->dexpr = NULL; - b = b->next; - } - CError_Error(CErrorStr205); - return; - } else { - scan_a = scan_a->next; - scan_b = scan_b->next; - } - } - -secondpart: - while (a && b) { - if (b->dexpr) - a->dexpr = b->dexpr; - else - b->dexpr = a->dexpr; - a = a->next; - b = b->next; - } -} - -void CheckDefaultArgs(FuncArg *args) { - FuncArg *scan; - - scan = args; - while (scan && !scan->dexpr) - scan = scan->next; - - while (scan && scan != &elipsis && scan != &oldstyle) { - if (!scan->dexpr) { - while (args) { - args->dexpr = NULL; - args = args->next; - } - CError_Error(CErrorStr205); - return; - } - scan = scan->next; - } -} - -static void CDecl_FuncRedeclCheck(Object *obj, DeclInfo *declinfo, Boolean flag) { - if (declinfo->storageclass == TK_STATIC && obj->sclass != TK_STATIC) { - if (copts.cplusplus) - CError_Error(CErrorStr260); - else - obj->sclass = TK_STATIC; - } - - obj->qual |= declinfo->qual; - if (flag) - CheckDefaultArgs(TYPE_FUNC(obj->type)->args); - else - MergeDefaultArgs(TYPE_FUNC(obj->type)->args, TYPE_FUNC(declinfo->thetype)->args); - - if (!declinfo->x45) - TYPE_FUNC(obj->type)->args = TYPE_FUNC(declinfo->thetype)->args; -} - -Object *CDecl_GetFunctionObject(DeclInfo *declinfo, NameSpace *nspace, Boolean *pflag, Boolean someotherflag) { - NameSpace *nspace2; - Type *type; - Object *obj; - NameSpaceObjectList *list; - TypeMemberFunc tmp; - Boolean r27; - Boolean outflag; - - r27 = 0; - if (pflag) - *pflag = 0; - - nspace2 = declinfo->nspace; - if (!nspace2) - nspace2 = cscope_current; - - CError_QualifierCheck(declinfo->qual & ~(Q_ALIGNED_MASK | Q_WEAK | Q_20000 | Q_INLINE | Q_PASCAL | Q_ASM | Q_VOLATILE | Q_CONST)); - switch (TYPE_FUNC(declinfo->thetype)->functype->type) { - case TYPEFUNC: - case TYPEARRAY: - CError_Error(CErrorStr128); - TYPE_FUNC(declinfo->thetype)->functype = TYPE(&stsignedint); - break; - } - - if (nspace2->theclass) { - CError_ASSERT(1969, declinfo->name); - if (!nspace2->theclass->size) - CDecl_CompleteType(TYPE(nspace2->theclass)); - if (!(list = CScope_GetLocalObject(nspace2, declinfo->name))) { - CError_Error(CErrorStr140, declinfo->name->name); - return NULL; - } - - obj = OBJECT(list->object); - type = obj->type; - if (!IS_TYPE_FUNC(type)) { - CError_Error(CErrorStr249, CError_GetObjectName(obj), type, obj->qual, declinfo->thetype, declinfo->qual); - return NULL; - } - - if (declinfo->has_expltargs) - return CTempl_TemplateFunctionCheck(declinfo, list); - - if (declinfo->x3C || (list->next && list->next->object->otype == OT_OBJECT)) { - if (TYPE_FUNC(declinfo->thetype)->flags & (FUNC_CONST | FUNC_VOLATILE)) { - CDecl_AddThisPointerArgument(TYPE_FUNC(declinfo->thetype), nspace2->theclass); - obj = CDecl_OverloadFunctionObject(list, declinfo, NULL, OverloadMode2, someotherflag); - if (!obj) - return NULL; - } else { - obj = CDecl_OverloadFunctionObject(list, declinfo, NULL, OverloadMode3, someotherflag); - if (!obj) - return NULL; - if (!TYPE_METHOD(obj->type)->is_static) - CDecl_AddThisPointerArgument(TYPE_FUNC(declinfo->thetype), nspace2->theclass); - } - } else { - if (TYPE_METHOD(type)->is_static) { - if (nspace2->theclass->sominfo) - CSOM_FixNewDeleteFunctype(TYPE_FUNC(declinfo->thetype)); - } else { - CDecl_AddThisPointerArgument(TYPE_FUNC(declinfo->thetype), nspace2->theclass); - } - - if (copts.cpp_extensions) { - declinfo->qual |= obj->qual & (Q_PASCAL | Q_CONST); - TYPE_FUNC(declinfo->thetype)->qual |= TYPE_FUNC(obj->type)->qual & (Q_PASCAL | Q_CONST); - TYPE_FUNC(declinfo->thetype)->flags |= TYPE_FUNC(obj->type)->flags & (FUNC_FLAGS_4000000 | FUNC_FLAGS_10000000); - } - - if (!is_typesame(declinfo->thetype, obj->type) || (declinfo->qual & (Q_PASCAL | Q_CONST)) != (obj->qual & (Q_PASCAL | Q_CONST))) { - tmp = *TYPE_METHOD(obj->type); - *(TYPE_FUNC(&tmp)) = *TYPE_FUNC(declinfo->thetype); - tmp.flags |= FUNC_METHOD; - CError_Error(CErrorStr249, CError_GetObjectName(obj), obj->type, obj->qual, &tmp, declinfo->qual); - } - - if (TYPE_FUNC(declinfo->thetype)->exspecs || TYPE_FUNC(obj->type)->exspecs) - CExcept_CompareSpecifications(TYPE_FUNC(declinfo->thetype)->exspecs, TYPE_FUNC(obj->type)->exspecs); - } - - CDecl_FuncRedeclCheck(obj, declinfo, 0); - if (declinfo->x3C) { - if (obj->nspace->theclass && !(obj->nspace->theclass->flags & CLASS_IS_TEMPL_INST)) - CError_Error(CErrorStr335); - declinfo->x3C = 0; - } - } else { - if (TYPE_FUNC(declinfo->thetype)->flags & (FUNC_VOLATILE | FUNC_CONST)) - CError_Error(CErrorStr384); - - if (declinfo->operator_token && !CDecl_CheckOperatorType(declinfo, 0)) - return NULL; - - list = CScope_GetLocalObject(nspace2, declinfo->name); - if (declinfo->has_expltargs) - return CTempl_TemplateFunctionCheck(declinfo, list); - - if (list) { - if (copts.cplusplus) { - obj = CDecl_OverloadFunctionObject(list, declinfo, &outflag, OverloadMode0, someotherflag); - if (!obj) - return NULL; - if (pflag) - *pflag = outflag; - if (nspace) - obj->nspace = nspace; - } else { - obj = OBJECT(list->object); - if (!is_typesame(declinfo->thetype, obj->type) || (declinfo->qual & (Q_CONST | Q_PASCAL)) != (obj->qual & (Q_CONST | Q_PASCAL))) { - CError_Error(CErrorStr249, CError_GetObjectName(obj), obj->type, obj->qual, declinfo->thetype, declinfo->qual); - r27 = 1; - if (!IS_TYPE_FUNC(obj->type)) - return NULL; - } - } - - if (!r27 && pflag) - CDecl_FuncRedeclCheck(obj, declinfo, *pflag); - } else { - if (declinfo->nspace) - CError_Error(CErrorStr336); - - if (declinfo->has_expltargs) { - if (declinfo->name) - CError_Error(CErrorStr140, declinfo->name->name); - else - CError_Error(CErrorStr127); - } - - obj = CParser_NewFunctionObject(declinfo); - if (nspace) - obj->nspace = nspace; - if (pflag) - *pflag = 1; - else - CError_Error(CErrorStr127); - - CheckDefaultArgs(TYPE_FUNC(obj->type)->args); - CScope_AddObject(nspace2, declinfo->name, OBJ_BASE(obj)); - } - } - - return obj; -} - -void CDecl_TypedefDeclarator(DeclInfo *declinfo) { - NameSpace *nspace; - NameSpaceObjectList *list; - ObjType *objt; - - nspace = declinfo->nspace; - if (!nspace) - nspace = cscope_current; - - CError_QualifierCheck(declinfo->qual & ~(Q_ALIGNED_MASK | Q_REFERENCE | Q_PASCAL | Q_VOLATILE | Q_CONST)); - if (declinfo->x48 || declinfo->x44) - CError_Error(CErrorStr121); - if (declinfo->operator_token) - CError_Error(CErrorStr193); - - objt = NULL; - list = CScope_FindName(nspace, declinfo->name); - if (list) { - switch (list->object->otype) { - case OT_TYPE: - objt = OBJ_TYPE(list->object); - break; - case OT_TYPETAG: - break; - case OT_NAMESPACE: - CError_Error(CErrorStr321); - return; - case OT_ENUMCONST: - case OT_OBJECT: - CError_Error(CErrorStr322); - return; - default: - CError_FATAL(2156); - } - } - - if (objt) { - const UInt32 mask = Q_ALIGNED_MASK | Q_REFERENCE | Q_PASCAL | Q_VOLATILE | Q_CONST; - if (!is_typesame(objt->type, declinfo->thetype) || (objt->qual & mask) != (declinfo->qual & mask)) { - CError_Error(CErrorStr249, declinfo->name->name, objt->type, objt->qual, declinfo->thetype, declinfo->qual); - } else if (!copts.cplusplus && (copts.pedantic || copts.ANSIstrict)) { - if (copts.pedantic) - CError_Warning(CErrorStr122, declinfo->name->name); - else - CError_Error(CErrorStr122, declinfo->name->name); - } - return; - } - - objt = galloc(sizeof(ObjType)); - memclrw(objt, sizeof(ObjType)); - objt->otype = OT_TYPE; - objt->access = ACCESSPUBLIC; - objt->type = declinfo->thetype; - objt->qual = declinfo->qual; - CScope_AddObject(nspace, declinfo->name, OBJ_BASE(objt)); - - if (nspace->theclass && (nspace->theclass->flags & CLASS_IS_TEMPL) && - CTemplTool_IsTemplateArgumentDependentType(declinfo->thetype)) - CTemplClass_RegisterObjectDef(TEMPL_CLASS(nspace->theclass), OBJ_BASE(objt)); - - if (copts.cplusplus) { - if (IS_TYPE_CLASS(declinfo->thetype) && IsTempName(TYPE_CLASS(declinfo->thetype)->classname)) { - TYPE_CLASS(declinfo->thetype)->classname = declinfo->name; - TYPE_CLASS(declinfo->thetype)->nspace->name = declinfo->name; - } - if (IS_TYPE_ENUM(declinfo->thetype) && IsTempName(TYPE_ENUM(declinfo->thetype)->enumname)) { - TYPE_ENUM(declinfo->thetype)->enumname = declinfo->name; - } - } - - if (cparamblkptr->browseoptions.recordTypedefs && declinfo->file->recordbrowseinfo) - CBrowse_NewTypedef(nspace, declinfo->name, declinfo->file, declinfo->file2, declinfo->sourceoffset, CPrep_BrowserFileOffset()); -} - -static void CDecl_DataDeclarator(DeclInfo *declinfo, AccessType access, Boolean flag) { - NameSpaceObjectList *list; - Object *obj; - NameSpace *nspace; - Boolean tmpflag; - ENode *expr; - - nspace = declinfo->nspace; - if (!nspace) - nspace = cscope_current; - - CError_QualifierCheck(declinfo->qual & ~(Q_ALIGNED_MASK | Q_WEAK | Q_20000 | Q_PASCAL | Q_VOLATILE | Q_CONST)); - if (declinfo->x48 || declinfo->x44) - CError_Error(CErrorStr121); - if (declinfo->operator_token) - CError_Error(CErrorStr193); - - obj = NULL; - list = CScope_FindName(nspace, declinfo->name); - if (list) { - switch (list->object->otype) { - case OT_OBJECT: - obj = OBJECT(list->object); - if (flag) - CError_Error(CErrorStr122, declinfo->name->name); - break; - case OT_TYPETAG: - break; - case OT_NAMESPACE: - CError_Error(CErrorStr321); - return; - case OT_ENUMCONST: - case OT_TYPE: - CError_Error(CErrorStr322); - break; - case OT_MEMBERVAR: - CError_Error(CErrorStr221); - break; - default: - CError_FATAL(2281); - } - } - - if (copts.cplusplus) { - if (!flag) - CDecl_CompleteType(declinfo->thetype); - switch (declinfo->storageclass) { - case TK_EXTERN: - if (tk == '=' || tk == '(') - declinfo->storageclass = 0; - break; - case 0: - if (CParser_IsConst(declinfo->thetype, declinfo->qual)) { - if ((!obj && !nspace->theclass) || (obj && obj->sclass != TK_EXTERN && !obj->nspace->theclass)) - declinfo->storageclass = TK_STATIC; - } - break; - } - } else { - if (declinfo->storageclass == TK_EXTERN && tk == '=') - declinfo->storageclass = 0; - } - - if (IS_TYPE_ARRAY(declinfo->thetype) && !declinfo->thetype->size && !declinfo->storageclass && tk != '=') - declinfo->storageclass = TK_EXTERN; - - if (obj) { - if ((!obj->type->size || !declinfo->thetype->size) && IS_TYPE_ARRAY(declinfo->thetype) && IS_TYPE_ARRAY(obj->type)) - tmpflag = is_typesame(TYPE_POINTER(declinfo->thetype)->target, TYPE_POINTER(obj->type)->target); - else - tmpflag = is_typesame(declinfo->thetype, obj->type); - - if (!tmpflag || (obj->qual & (Q_PASCAL | Q_VOLATILE | Q_CONST)) != (declinfo->qual & (Q_PASCAL | Q_VOLATILE | Q_CONST))) - CError_Error(CErrorStr249, CError_GetObjectName(obj), obj->type, obj->qual, declinfo->thetype, declinfo->qual); - - if (obj->qual & Q_INLINE_DATA) { - if (tk == ',' || tk == ';') - return; - CError_Error(CErrorStr333, obj); - } - - if (declinfo->storageclass != TK_EXTERN) { - if (obj->sclass != TK_EXTERN && declinfo->storageclass && obj->sclass != declinfo->storageclass) - CError_Error(CErrorStr333, obj); - - if (tmpflag) { - obj->sclass = declinfo->storageclass; - obj->qual |= declinfo->qual; - if (declinfo->thetype->size) - obj->type = declinfo->thetype; - } - - CParser_UpdateObject(obj, declinfo); - } else { - flag = 1; - } - } else { - if (declinfo->nspace) - CError_Error(CErrorStr336); - if (IS_TYPE_CLASS(declinfo->thetype) && TYPE_CLASS(declinfo->thetype)->sominfo) - CError_Error(CErrorStr288); - if (!CanCreateObject(declinfo->thetype)) - declinfo->thetype = TYPE(&stsignedint); - - obj = CParser_NewGlobalDataObject(declinfo); - obj->access = access; - CScope_AddObject(nspace, declinfo->name, OBJ_BASE(obj)); - - if (nspace->theclass && (nspace->theclass->flags & CLASS_IS_TEMPL) && - CTemplTool_IsTemplateArgumentDependentType(declinfo->thetype)) - CTemplClass_RegisterObjectDef(TEMPL_CLASS(nspace->theclass), OBJ_BASE(obj)); - - if (flag && nspace->theclass && cparamblkptr->browseoptions.recordClasses) - CBrowse_AddClassMemberData(obj, CPrep_BrowserTokenOffset(&member_fileoffset) + 1, CPrep_BrowserFileOffset()); - } - - if (!flag) { - if (declinfo->nspace) { - CScopeSave save; - CScope_SetNameSpaceScope(declinfo->nspace, &save); - CInit_InitializeData(obj); - CScope_RestoreScope(&save); - - if (declinfo->x3C && obj->nspace->theclass && (TYPE_CLASS(obj->nspace->theclass)->flags & CLASS_IS_TEMPL_INST)) - declinfo->x3C = 0; - } else { - CInit_InitializeData(obj); - } - - if (declinfo->file->recordbrowseinfo && obj->sclass != TK_EXTERN) - CBrowse_NewData(obj, declinfo->file, declinfo->file2, declinfo->sourceoffset, CPrep_BrowserFileOffset()); - } else if (tk == '=') { - tk = lex(); - expr = CExpr_IntegralConstOrDepExpr(); - if (IS_TYPE_TEMPLATE(obj->type) || !ENODE_IS(expr, EINTCONST)) { - CError_ASSERT(2426, nspace->theclass && (nspace->theclass->flags & CLASS_IS_TEMPL)); - CTemplClass_RegisterObjectInit(TEMPL_CLASS(nspace->theclass), obj, expr); - } else if ((obj->qual & Q_CONST) && IS_TYPE_INT_OR_ENUM(obj->type)) { - obj->u.data.u.intconst = expr->data.intval; - obj->qual |= Q_INLINE_DATA | Q_20000; - } else { - CError_Error(CErrorStr354, obj->name->name); - } - } -} - -Boolean CDecl_FunctionDeclarator(DeclInfo *declinfo, NameSpace *nspace, Boolean flag, Boolean flag2) { - Object *obj; - Boolean pflag; - - obj = CDecl_GetFunctionObject(declinfo, nspace, &pflag, 0); - if (obj) { - if (declinfo->x44 || tk == '{' || tk == TK_TRY || (declinfo->x4B && tk == ':') || (!copts.cplusplus && isdeclaration(0, 0, 0, 0))) { - if (!flag || cscope_currentfunc) { - CError_Error(CErrorStr127); - if (cscope_currentfunc) - return 0; - } - - if (obj->nspace == cscope_root && !strcmp(obj->name->name, "main")) { - if (obj->sclass == TK_STATIC || (copts.ANSIstrict && TYPE_FUNC(obj->type)->functype != (Type *) &stsignedint)) - CError_Error(CErrorStr334); - } else if (copts.checkprotos && (pflag || declinfo->x64)) { - if (obj->sclass != TK_STATIC && !(obj->qual & Q_INLINE) && !obj->nspace->is_unnamed) - CError_Warning(CErrorStr178); - } - - CFunc_ParseFuncDef(obj, declinfo, NULL, 0, 0, NULL); - if (declinfo->file->recordbrowseinfo) - CBrowse_NewFunction( - obj, - declinfo->file, - declinfo->file2, - declinfo->sourceoffset, - CPrep_BrowserFileOffset()); - - if (copts.cplusplus && lookahead() == ';') - tk = lex(); - return 0; - } - } - - return 1; -} - -static void CDecl_ParseSpecialMember(DeclInfo *declinfo, Boolean flag) { - Object *r28; - NameSpace *r25; - - if (!(r28 = declinfo->x10)) { - CError_ASSERT(2544, declinfo->x14); - r28 = OBJECT(declinfo->x14->object); - CError_ASSERT(2546, r28->otype == OT_OBJECT); - } - - if (!r28->nspace->theclass) { - CError_Error(CErrorStr121); - return; - } - - if (IS_TYPE_FUNC(r28->type)) { - if (TYPE_FUNC(r28->type)->flags & (FUNC_IS_CTOR | FUNC_IS_DTOR)) { - if (r28->nspace->theclass->sominfo) - declinfo->thetype = TYPE(&stvoid); - else - declinfo->thetype = TYPE(&void_ptr); - declinfo->nspace = r28->nspace; - declinfo->name = r28->name; - if (TYPE_FUNC(r28->type)->flags & FUNC_IS_CTOR) - declinfo->x4B = 1; - - if ((tk = lex()) == '(') { - tk = lex(); - - r25 = cscope_current; - cscope_current = r28->nspace; - CDecl_ParseDirectFuncDecl(declinfo); - cscope_current = r25; - - if (IS_TYPE_FUNC(declinfo->thetype)) { - if (TYPE_FUNC(r28->type)->flags & FUNC_IS_CTOR) { - if ((r28->nspace->theclass->flags & CLASS_HAS_VBASES) && !r28->nspace->theclass->sominfo) - CDecl_AddArgument(TYPE_FUNC(declinfo->thetype), TYPE(&stsignedshort)); - } else { - if (!r28->nspace->theclass->sominfo) - CDecl_AddArgument(TYPE_FUNC(declinfo->thetype), TYPE(&stsignedshort)); - } - if (flag) - CDecl_FunctionDeclarator(declinfo, NULL, 1, 1); - } else { - CError_Error(CErrorStr121); - } - } else { - CError_Error(CErrorStr114); - } - return; - } else if (TYPE_FUNC(r28->type)->flags & FUNC_CONVERSION) { - CError_FATAL(2603); - - declinfo->thetype = TYPE_FUNC(r28->type)->functype; - declinfo->qual |= TYPE_FUNC(r28->type)->qual; - declinfo->nspace = r28->nspace; - declinfo->name = r28->name; - - if ((tk = lex()) == '(') { - tk = lex(); - CDecl_ParseDirectFuncDecl(declinfo); - if (IS_TYPE_FUNC(declinfo->thetype)) { - TYPE_FUNC(declinfo->thetype)->flags |= FUNC_CONVERSION; - if (flag) - CDecl_FunctionDeclarator(declinfo, NULL, 1, 1); - } else { - CError_Error(CErrorStr121); - } - } else { - CError_Error(CErrorStr114); - } - return; - } else { - declinfo->thetype = TYPE(&stsignedint); - declinfo->nspace = r28->nspace; - declinfo->name = r28->name; - - if ((tk = lex()) == '(') { - tk = lex(); - - r25 = cscope_current; - cscope_current = r28->nspace; - CDecl_ParseDirectFuncDecl(declinfo); - cscope_current = r25; - - if (IS_TYPE_FUNC(declinfo->thetype)) { - if (flag) - CDecl_FunctionDeclarator(declinfo, NULL, 1, 1); - return; - } - } else { - CError_Error(CErrorStr114); - } - } - } - - CError_Error(CErrorStr121); -} - -void CDecl_ScanDeclarator(DeclInfo *declinfo) { - if (declinfo->x14 || declinfo->x10) { - CDecl_ParseSpecialMember(declinfo, 0); - CDecl_GetFunctionObject(declinfo, NULL, NULL, 1); - return; - } - - if (IS_TYPE_FUNC(declinfo->thetype)) { - TypeFunc *copy = galloc(sizeof(TypeFunc)); - *copy = *TYPE_FUNC(declinfo->thetype); - declinfo->thetype = TYPE(copy); - } - scandeclarator(declinfo); - if (!declinfo->name) { - CError_Error(CErrorStr121); - return; - } - - if (declinfo->storageclass && declinfo->storageclass != TK_EXTERN) - CError_Error(CErrorStr177); - - if (IS_TYPE_FUNC(declinfo->thetype)) { - CDecl_GetFunctionObject(declinfo, NULL, NULL, 1); - return; - } - - if (declinfo->x48 || declinfo->x44) - CError_Error(CErrorStr121); - - if (declinfo->operator_token) - CError_Error(CErrorStr193); - - if ( - (declinfo->qual & ~(Q_ALIGNED_MASK | Q_WEAK | Q_20000 | Q_PASCAL | Q_VOLATILE | Q_CONST)) || - (declinfo->storageclass == TK_TYPEDEF && (declinfo->qual & ~(Q_ALIGNED_MASK | Q_REFERENCE | Q_PASCAL | Q_VOLATILE | Q_CONST))) - ) - CError_Error(CErrorStr176); -} - -void scandeclaratorlist(DeclInfo *declinfo) { - CScopeSave savescope; - Type *r30; - UInt32 r29; - Boolean r28; - - if (declinfo->x14 || declinfo->x10) { - CDecl_ParseSpecialMember(declinfo, 1); - return; - } - - CScope_GetScope(&savescope); - CError_ASSERT(2707, declinfo->thetype); - - r28 = 1; - while (1) { - r30 = declinfo->thetype; - r29 = declinfo->qual; - declinfo->nspace = NULL; - declinfo->operator_token = 0; - if (IS_TYPE_FUNC(r30)) { - declinfo->thetype = galloc(sizeof(TypeFunc)); - *TYPE_FUNC(declinfo->thetype) = *TYPE_FUNC(r30); - } - declinfo->name = NULL; - scandeclarator(declinfo); - if (!declinfo->name) { - CError_Error(CErrorStr121); - break; - } - - if (declinfo->storageclass != TK_TYPEDEF) { - if (IS_TYPE_FUNC(declinfo->thetype)) { - if (!CDecl_FunctionDeclarator(declinfo, NULL, r28, 1)) - return; - } else { - CDecl_DataDeclarator(declinfo, ACCESSPUBLIC, 0); - } - } else { - CDecl_TypedefDeclarator(declinfo); - } - - CScope_RestoreScope(&savescope); - declinfo->thetype = r30; - declinfo->qual = r29; - - if (tk != ',') - break; - tk = lex(); - r28 = 0; - } - - if (tk != ';') - CError_Error(CErrorStr123); -} - -static TypeIntegral *CDecl_FindSignedType(short size) { - if (stsignedchar.size == size) - return &stsignedchar; - if (stsignedshort.size == size) - return &stsignedshort; - if (stsignedint.size == size) - return &stsignedint; - if (stsignedlong.size == size) - return &stsignedlong; - if (copts.longlong && copts.longlong_enums && stsignedlonglong.size == size) - return &stsignedlonglong; - return &stsignedlong; -} - -static TypeIntegral *CDecl_FindUnsignedType(short size) { - if (stunsignedchar.size == size) - return &stunsignedchar; - if (stunsignedshort.size == size) - return &stunsignedshort; - if (stunsignedint.size == size) - return &stunsignedint; - if (stunsignedlong.size == size) - return &stunsignedlong; - if (copts.longlong && copts.longlong_enums && stunsignedlonglong.size == size) - return &stunsignedlonglong; - return &stunsignedlong; -} - -static TypeIntegral *CDecl_IterateIntegralEnumType(int *t) { - switch (*t) { - case 0: - *t = 1; - return &stsignedchar; - case 1: - if (stsignedshort.size > stsignedchar.size) { - *t = 2; - return &stsignedshort; - } - case 2: - if (stsignedint.size > stsignedshort.size) { - *t = 3; - return &stsignedint; - } - case 3: - if (stsignedlong.size > stsignedint.size) { - *t = 4; - return &stsignedlong; - } - case 4: - *t = 5; - if (stsignedlonglong.size > stsignedlong.size && copts.longlong && copts.longlong_enums) - return &stsignedlonglong; - default: - return NULL; - } -} - -static TypeIntegral *CDecl_IterateUIntegralEnumType(int *t) { - switch (*t) { - case 0: - *t = 1; - return &stunsignedchar; - case 1: - if (stunsignedshort.size > stunsignedchar.size) { - *t = 2; - return &stunsignedshort; - } - case 2: - if (stunsignedint.size > stunsignedshort.size) { - *t = 3; - return &stunsignedint; - } - case 3: - if (stunsignedlong.size > stunsignedint.size) { - *t = 4; - return &stunsignedlong; - } - case 4: - *t = 5; - if (stunsignedlonglong.size > stunsignedlong.size && copts.longlong && copts.longlong_enums) - return &stunsignedlonglong; - default: - return NULL; - } -} - -static TypeEnum *CDecl_OldParseEnumList(TypeEnum *tenum, HashNameNode *name) { - AccessType access; - Boolean has_template_value; - Boolean r24; - Boolean r23; - ObjEnumConst *oec; - ObjEnumConst *last; - Boolean overflowed; - CInt64 val; - CInt64 minimum; - CInt64 maximum; - CInt64 var_74; - CInt64 unused; - Type *basetype; - Type *basetype2; - CPrepFileInfo *fileinfo; - SInt32 offset; - ENode *expr; - Type *tmp; - - if (!tenum) { - tenum = galloc(sizeof(TypeEnum)); - memclrw(tenum, sizeof(TypeEnum)); - tenum->type = TYPEENUM; - tenum->nspace = cscope_current; - - if (name) { - tenum->enumname = name; - CScope_DefineTypeTag(cscope_current, name, TYPE(tenum)); - } - - if (!cscope_current->is_global) { - do { - tenum->nspace = tenum->nspace->parent; - } while (!tenum->nspace->is_global); - if (tenum->enumname) - tenum->enumname = CParser_AppendUniqueNameFile(tenum->enumname->name); - } - } - - if (cscope_current->theclass && (cscope_current->theclass->flags & CLASS_IS_TEMPL)) { - CTemplClass_RegisterEnumType(TEMPL_CLASS(cscope_current->theclass), tenum); - } - - access = cscope_current->theclass ? global_access : ACCESSPUBLIC; - last = NULL; - unused = cint64_zero; - val = cint64_zero; - minimum = cint64_zero; - maximum = cint64_zero; - r23 = 0; - if (copts.enumsalwaysint) { - basetype = TYPE(&stsignedint); - r24 = 1; - } else { - basetype = TYPE(&stunsignedchar); - r24 = 0; - } - - tk = lex(); - if (!copts.cplusplus || tk != '}') { - do { - if (tk != TK_IDENTIFIER) { - if (tk == '}') { - if (copts.cpp_extensions) - break; - if (!copts.warn_extracomma) - break; - } - CError_Warning(CErrorStr107); - break; - } - - oec = galloc(sizeof(ObjEnumConst)); - memclrw(oec, sizeof(ObjEnumConst)); - oec->otype = OT_ENUMCONST; - oec->access = access; - oec->type = TYPE(tenum); - oec->name = tkidentifier; - CPrep_BrowserFilePosition(&fileinfo, &offset); - overflowed = 0; - if ((tk = lex()) == '=') { - tk = lex(); - val = CExpr_IntegralConstExprType(&basetype2); - if (!CInt64_IsNegative(&val) || is_unsigned(basetype2)) { - if (CInt64_GreaterU(val, minimum)) { - minimum = val; - overflowed = 1; - } - } else { - if (CInt64_Less(val, maximum)) { - maximum = val; - overflowed = 1; - } - if (!r24) { - basetype = TYPE(&stsignedchar); - r24 = 1; - } - } - r23 = 0; - } else { - if (r23) - CError_Error(CErrorStr154); - - if (!r24 || !CInt64_IsNegative(&val)) { - if (CInt64_GreaterU(val, minimum)) { - minimum = val; - overflowed = 1; - } - } else { - if (CInt64_Less(val, maximum)) { - maximum = val; - overflowed = 1; - } - } - } - - if (copts.enumsalwaysint) { - if (copts.ANSIstrict) { - if (!CInt64_IsInRange(val, stsignedint.size)) - CError_Error(CErrorStr154); - } else { - if (!CInt64_IsInRange(val, stsignedint.size) && !CInt64_IsInURange(val, stunsignedint.size)) - CError_Error(CErrorStr154); - } - } else if (r24) { - switch (basetype->size) { - case 1: - if (CInt64_IsInRange(minimum, 1) && CInt64_IsInRange(maximum, 1)) - break; - basetype = TYPE(CDecl_FindSignedType(2)); - case 2: - if (CInt64_IsInRange(minimum, 2) && CInt64_IsInRange(maximum, 2)) - break; - basetype = TYPE(CDecl_FindSignedType(4)); - case 4: - if (CInt64_IsInRange(minimum, 4) && CInt64_IsInRange(maximum, 4)) - break; - basetype = TYPE(CDecl_FindSignedType(8)); - if (basetype->size != 8) { - if (!copts.ANSIstrict && CInt64_IsInRange(maximum, 4) && CInt64_IsInURange(minimum, 4)) - break; - if (overflowed) - CError_Error(CErrorStr154); - break; - } - case 8: - if (CInt64_Equal(val, minimum) && CInt64_IsNegative(&val)) - CError_Error(CErrorStr154); - break; - default: - CError_FATAL(3071); - } - } else { - switch (basetype->size) { - case 1: - if (CInt64_IsInURange(minimum, 1)) - break; - basetype = TYPE(CDecl_FindUnsignedType(2)); - case 2: - if (CInt64_IsInURange(minimum, 2)) - break; - basetype = TYPE(CDecl_FindUnsignedType(4)); - case 4: - if (CInt64_IsInURange(minimum, 4)) - break; - basetype = TYPE(CDecl_FindUnsignedType(8)); - if (basetype->size != 8) { - if (overflowed) - CError_Error(CErrorStr154); - break; - } - case 8: - break; - default: - CError_FATAL(3099); - } - } - - tenum->size = basetype->size; - tenum->enumtype = basetype; - oec->val = val; - CScope_AddObject(cscope_current, oec->name, OBJ_BASE(oec)); - - if (last) { - last->next = oec; - last = oec; - } else { - last = oec; - tenum->enumlist = oec; - } - - if (cparamblkptr->browseoptions.recordEnums) { - CPrepFileInfo *f = CPrep_BrowserCurrentFile(); - if (f->recordbrowseinfo) { - CBrowse_NewEnumConstant(cscope_current, oec->name, f, fileinfo, offset, CPrep_BrowserFileOffset()); - } - } - - var_74 = CInt64_Add(val, cint64_one); - if (r24) { - if (CInt64_IsNegative(&var_74) && !CInt64_IsNegative(&val)) - r23 = 1; - } else { - if (CInt64_IsZero(&var_74)) - r23 = 1; - } - val = var_74; - - if (tk != ',') - break; - tk = lex(); - } while (1); - } - - tenum->size = basetype->size; - tenum->enumtype = basetype; - - for (oec = tenum->enumlist; oec; oec = oec->next) - oec->type = TYPE(tenum); - - if (tk != '}') - CError_ErrorSkip(CErrorStr130); - else - tk = lex(); - - return tenum; -} - -static Type *CDecl_MaxType(Type *a, Type *b) { - if (a->size > b->size) - return a; - if (b->size > a->size) - return b; - if (is_unsigned(b)) - return b; - else - return a; -} - -void CDecl_ComputeUnderlyingEnumType(TypeEnum *tenum) { - ObjEnumConst *oec; - ObjEnumConst *oec2; - Type *r26; - int t; - - if (!copts.enumsalwaysint) { - for (oec2 = tenum->enumlist; oec2; oec2 = oec2->next) { - if (CInt64_IsNegative(&oec2->val) && !is_unsigned(oec2->type)) - break; - } - - if (oec2) { - CInt64 unused = cint64_zero; - CInt64 minimum = cint64_zero; - CInt64 maximum = cint64_zero; - for (oec = tenum->enumlist; oec; oec = oec->next) { - if (CInt64_IsNegative(&oec->val) && !is_unsigned(oec->type)) { - if (CInt64_Less(oec->val, minimum)) - minimum = oec->val; - } else { - if (CInt64_GreaterU(oec->val, maximum)) - maximum = oec->val; - } - } - - if (CInt64_IsNegative(&maximum)) - CError_Error(CErrorStr154); - - t = 0; - do { - r26 = TYPE(CDecl_IterateIntegralEnumType(&t)); - if (!r26) { - r26 = TYPE(&stsignedlong); - CError_Error(CErrorStr154); - break; - } - - if (CInt64_IsInRange(maximum, r26->size) && CInt64_IsInRange(minimum, r26->size)) - break; - if (r26->size == stsignedlong.size && !copts.ANSIstrict && CInt64_IsInRange(minimum, r26->size) && CInt64_IsInURange(maximum, r26->size)) - break; - } while (1); - } else { - CInt64 val = cint64_zero; - - for (oec = tenum->enumlist; oec; oec = oec->next) { - if (CInt64_GreaterU(oec->val, val)) - val = oec->val; - } - - t = 0; - do { - r26 = TYPE(CDecl_IterateUIntegralEnumType(&t)); - if (!r26) { - r26 = TYPE(&stunsignedlong); - CError_Error(CErrorStr154); - break; - } - if (CInt64_IsInURange(val, r26->size)) - break; - } while (1); - } - } else { - r26 = TYPE(&stsignedint); - } - - tenum->size = r26->size; - tenum->enumtype = r26; - for (oec = tenum->enumlist; oec; oec = oec->next) - oec->type = TYPE(tenum); -} - -static Type *CDecl_FindUnderlyingType(short size, CInt64 *a, CInt64 *b) { - if (CInt64_IsZero(a)) { - if (size <= stsignedchar.size && CInt64_IsInURange(*b, stunsignedchar.size)) - return TYPE(&stunsignedchar); - if (size <= stsignedshort.size && CInt64_IsInURange(*b, stunsignedshort.size)) - return TYPE(&stunsignedshort); - if (size <= stsignedint.size && CInt64_IsInURange(*b, stunsignedint.size)) - return TYPE(&stunsignedint); - if (size <= stsignedlong.size && CInt64_IsInURange(*b, stunsignedlong.size)) - return TYPE(&stunsignedlong); - if (size <= stsignedlonglong.size && copts.longlong && copts.longlong_enums && CInt64_IsInURange(*b, stunsignedlonglong.size)) - return TYPE(&stunsignedlonglong); - } else { - if (size <= stsignedchar.size && CInt64_IsInRange(*a, stsignedchar.size) && CInt64_IsInRange(*b, stsignedchar.size)) - return TYPE(&stsignedchar); - if (size <= stsignedshort.size && CInt64_IsInRange(*a, stsignedshort.size) && CInt64_IsInRange(*b, stsignedshort.size)) - return TYPE(&stsignedshort); - if (size <= stsignedint.size && CInt64_IsInRange(*a, stsignedint.size) && CInt64_IsInRange(*b, stsignedint.size)) - return TYPE(&stsignedint); - if (size <= stsignedlong.size && CInt64_IsInRange(*a, stsignedlong.size) && CInt64_IsInRange(*b, stsignedlong.size)) - return TYPE(&stsignedlong); - if (size <= stsignedlonglong.size && copts.longlong && copts.longlong_enums && CInt64_IsInRange(*a, stsignedlonglong.size) && CInt64_IsInRange(*b, stsignedlonglong.size)) - return TYPE(&stsignedlonglong); - if (!copts.ANSIstrict && size <= stsignedlong.size && CInt64_IsInRange(*a, stsignedlong.size) && CInt64_IsInURange(*b, stunsignedlong.size)) - return TYPE(&stsignedlong); - } - - return NULL; -} - -static TypeEnum *CDecl_ParseEnumList(TypeEnum *tenum, HashNameNode *name) { - AccessType access; - TemplClass *tmclass; - ObjEnumConst *oec; - Boolean has_template_value; - Boolean overflowed; - Boolean is_first; - CInt64 val; - CInt64 minimum; - CInt64 maximum; - CInt64 unused; - Type *basetype; - CPrepFileInfo *fileinfo; - SInt32 offset; - ENode *expr; - Type *tmp; - ObjEnumConst *last; - - if (!tenum) { - tenum = galloc(sizeof(TypeEnum)); - memclrw(tenum, sizeof(TypeEnum)); - tenum->type = TYPEENUM; - tenum->nspace = cscope_current; - - if (name) { - tenum->enumname = name; - CScope_DefineTypeTag(cscope_current, name, TYPE(tenum)); - } - - if (!cscope_current->is_global) { - do { - tenum->nspace = tenum->nspace->parent; - } while (!tenum->nspace->is_global); - if (tenum->enumname) - tenum->enumname = CParser_AppendUniqueNameFile(tenum->enumname->name); - } - } - - if (cscope_current->theclass && (cscope_current->theclass->flags & CLASS_IS_TEMPL)) { - tmclass = TEMPL_CLASS(cscope_current->theclass); - CTemplClass_RegisterEnumType(tmclass, tenum); - } else { - tmclass = NULL; - } - - access = cscope_current->theclass ? global_access : ACCESSPUBLIC; - last = NULL; - is_first = 1; - has_template_value = 0; - unused = cint64_zero; - val = cint64_zero; - minimum = cint64_zero; - maximum = cint64_zero; - basetype = copts.enumsalwaysint ? TYPE(&stsignedint) : TYPE(&stsignedchar); - tenum->size = basetype->size; - tenum->enumtype = basetype; - - do { - if ((tk = lex()) != TK_IDENTIFIER) { - if (tk == '}') { - if (is_first) { - if (copts.cplusplus) - break; - } else { - if (!copts.warn_extracomma) - break; - if (copts.c9x) - break; - if (copts.cpp_extensions) - break; - } - CError_Warning(CErrorStr107); - } else { - CError_Error(CErrorStr107); - } - break; - } - - oec = galloc(sizeof(ObjEnumConst)); - memclrw(oec, sizeof(ObjEnumConst)); - oec->otype = OT_ENUMCONST; - oec->access = access; - oec->name = tkidentifier; - CPrep_BrowserFilePosition(&fileinfo, &offset); - overflowed = 0; - if ((tk = lex()) == '=') { - tk = lex(); - if (tmclass) { - expr = CExpr_IntegralConstOrDepExpr(); - if (ENODE_IS(expr, EINTCONST)) { - val = expr->data.intval; - basetype = expr->rtype; - has_template_value = 0; - } else { - val = cint64_zero; - basetype = TYPE(tenum); - CTemplClass_RegisterEnumerator(tmclass, oec, expr); - has_template_value = 1; - } - } else { - val = CExpr_IntegralConstExprType(&basetype); - has_template_value = 0; - } - } else if (has_template_value) { - CTemplClass_RegisterEnumerator(tmclass, oec, NULL); - } else if (!is_first) { - if (is_unsigned(basetype)) { - val = CInt64_Add(val, cint64_one); - if (CInt64_IsZero(&val)) - overflowed = 1; - } else if (!CInt64_IsNegative(&val)) { - val = CInt64_Add(val, cint64_one); - if (CInt64_IsNegative(&val)) - overflowed = 1; - } else { - val = CInt64_Add(val, cint64_one); - } - } - - if (!has_template_value) { - if (copts.enumsalwaysint) { - if (!CInt64_IsInRange(val, stsignedint.size) && (copts.ANSIstrict || !CInt64_IsInURange(val, stunsignedint.size))) - overflowed = 1; - basetype = TYPE(&stsignedint); - } else if (CInt64_IsNegative(&val) && !is_unsigned(basetype)) { - if (CInt64_Less(val, minimum)) { - minimum = val; - if ((tmp = CDecl_FindUnderlyingType(tenum->size, &minimum, &maximum))) { - tenum->size = tmp->size; - tenum->enumtype = tmp; - } else { - overflowed = 1; - } - } - } else { - if (CInt64_GreaterU(val, maximum)) { - maximum = val; - if ((tmp = CDecl_FindUnderlyingType(tenum->size, &minimum, &maximum))) { - tenum->size = tmp->size; - tenum->enumtype = tmp; - } else { - overflowed = 1; - } - } - } - } - - if (overflowed) - CError_Error(CErrorStr154); - - oec->val = val; - oec->type = basetype; - CScope_AddObject(cscope_current, oec->name, OBJ_BASE(oec)); - - if (last) { - last->next = oec; - last = oec; - } else { - last = oec; - tenum->enumlist = oec; - } - - if (cparamblkptr->browseoptions.recordEnums) { - CPrepFileInfo *f = CPrep_BrowserCurrentFile(); - if (f->recordbrowseinfo) { - CBrowse_NewEnumConstant(cscope_current, oec->name, f, fileinfo, offset, CPrep_BrowserFileOffset()); - } - } - - is_first = 0; - } while (tk == ','); - - for (oec = tenum->enumlist; oec; oec = oec->next) - oec->type = TYPE(tenum); - - if (tk != '}') - CError_ErrorSkip(CErrorStr130); - else - tk = lex(); - - return tenum; -} - -void scanenum(DeclInfo *declinfo) { - HashNameNode *name; - Type *type; - NameResult pr; - - if (tk == '{') { - declinfo->thetype = TYPE(CDecl_ParseEnumList(NULL, NULL)); - TYPE_ENUM(declinfo->thetype)->enumname = CParser_AppendUniqueNameFile("@enum"); - return; - } - - if (tk == TK_IDENTIFIER) { - name = tkidentifier; - if (lookahead() == '{') { - type = CScope_GetLocalTagType(cscope_current, name); - if (type) { - lex(); - do_shit: - if (type->size || !IS_TYPE_ENUM(type)) { - CError_Error(CErrorStr122, name->name); - declinfo->thetype = TYPE(CDecl_ParseEnumList(NULL, NULL)); - return; - } - declinfo->thetype = TYPE(CDecl_ParseEnumList(TYPE_ENUM(type), NULL)); - } else { - lex(); - declinfo->thetype = TYPE(CDecl_ParseEnumList(NULL, name)); - } - - if (cparamblkptr->browseoptions.recordEnums && declinfo->file->recordbrowseinfo) - CBrowse_NewEnum( - cscope_current, - TYPE_ENUM(declinfo->thetype)->enumname, - declinfo->file, - declinfo->file2, - declinfo->sourceoffset, - CPrep_BrowserFileOffset()); - return; - } else { - CError_ASSERT(3851, !copts.cplusplus || tk != ';'); - tkidentifier = name; - } - } - - if (CScope_ParseElaborateName(&pr)) { - if ((type = pr.type)) { - if (!IS_TYPE_ENUM(type)) - CError_Error(CErrorStr121); - if ((tk = lex()) == '{') - goto do_shit; - declinfo->thetype = type; - return; - } else { - CError_ASSERT(3865, pr.name_4); - if ((tk = lex()) == '{') { - declinfo->thetype = TYPE(CDecl_ParseEnumList(NULL, pr.name_4)); - return; - } else { - CError_Error(CErrorStr140, pr.name_4->name); - } - } - } else { - CError_Error(CErrorStr121); - } - - declinfo->thetype = TYPE(&stsignedint); -} - -void CDecl_ScanStructDeclarator(BigDeclInfo *bde) { - ENode *expr; - short val; - short bits; - Boolean is_bitfield; - TypeTemplDep *ttempl; - TypeBitfield *tbitfield; - Type *type; - - bde->declinfo2 = bde->declinfo; - bde->declinfo2.name = NULL; - bde->declinfo2.operator_token = 0; - bde->xCD = 0; - is_bitfield = 0; - - if (tk == ':') { - bde->declinfo2.name = no_name_node; - is_bitfield = 1; - } else { - bde->declinfo2.x50 = 1; - scandeclarator(&bde->declinfo2); - if (!bde->declinfo2.name) { - CError_Error(CErrorStr131); - return; - } - - if ((!copts.ANSIstrict || copts.c9x) && !bde->declinfo2.thetype->size && IS_TYPE_ARRAY(bde->declinfo2.thetype)) { - if (bde->declinfo2.storageclass != TK_STATIC && bde->declinfo2.storageclass != TK_TYPEDEF) { - type = TYPE_POINTER(bde->declinfo2.thetype)->target; - while (IS_TYPE_ARRAY(type)) - type = TYPE_POINTER(type)->target; - if (!IsCompleteType(type)) - return; - if (tk != ';' || lookahead() != '}') { - CError_Error(CErrorStr145); - return; - } - } - } else { - if (bde->declinfo2.storageclass != TK_STATIC && bde->declinfo2.storageclass != TK_TYPEDEF) { - if (!IS_TYPE_FUNC(bde->declinfo2.thetype) && !IsCompleteType(bde->declinfo2.thetype)) - return; - } - } - - if (IS_TYPE_CLASS(bde->declinfo2.thetype) && TYPE_CLASS(bde->declinfo2.thetype)->sominfo) { - CError_Error(CErrorStr287); - return; - } - - if (tk != ':') - goto not_a_bitfield; - } - - if (!IS_TYPE_INT_OR_ENUM(bde->declinfo2.thetype)) { - if (CTemplTool_IsTemplateArgumentDependentType(bde->declinfo2.thetype)) - goto fuckup; - CError_Error(CErrorStr138); - bde->declinfo2.thetype = TYPE(&stunsignedint); - } else if (copts.ANSIstrict && !copts.cplusplus) { - if (bde->declinfo2.thetype != TYPE(&stsignedint) && bde->declinfo2.thetype != TYPE(&stunsignedint)) { - CError_Error(CErrorStr138); - bde->declinfo2.thetype = TYPE(&stunsignedint); - } - } - - switch (bde->declinfo2.thetype->size) { - case 1: - bits = 8; - break; - case 2: - bits = 16; - break; - case 4: - bits = 32; - break; - default: - CError_Error(CErrorStr138); - return; - } -fuckup: - tk = lex(); - expr = CExpr_IntegralConstOrDepExpr(); - if (!ENODE_IS(expr, EINTCONST)) { - ttempl = TYPE_TEMPLATE(CDecl_NewTemplDepType(TEMPLDEP_BITFIELD)); - ttempl->u.bitfield.type = bde->declinfo2.thetype; - ttempl->u.bitfield.size = CInline_CopyExpression(expr, CopyMode1); - bde->declinfo2.thetype = TYPE(ttempl); - bde->xCD = 1; - return; - } - val = CInt64_GetULong(&expr->data.intval); - if (is_bitfield) { - if (val < 0 || val > bits) { - CError_Error(CErrorStr138); - return; - } - } else { - if (val <= 0 || val > bits) { - CError_Error(CErrorStr138); - return; - } - } - - tbitfield = galloc(sizeof(TypeBitfield)); - memclrw(tbitfield, sizeof(TypeBitfield)); - tbitfield->type = TYPEBITFIELD; - tbitfield->size = bde->declinfo2.thetype->size; - tbitfield->bitfieldtype = bde->declinfo2.thetype; - tbitfield->bitlength = val; - bde->declinfo2.thetype = TYPE(tbitfield); - - if (tk == TK_UU_ATTRIBUTE_UU) - CParser_ParseAttribute(NULL, &bde->declinfo2); - -not_a_bitfield: - bde->xCD = 1; -} - -static void CDecl_LayoutStruct(TypeStruct *tstruct) { - StructMember *member; - SInt32 r28; - StructMember *innermember; - SInt32 innerbase; - StructMember *newmember; - StructMember **memberp; - TypeBitfield *bf; - SInt32 r24; - Boolean r23; - SInt32 tmp; - - r28 = 0; - r23 = 0; - CMach_StructLayoutInitOffset(0); - for (member = tstruct->members; member; member = member->next) { - if (tstruct->stype == STRUCT_TYPE_UNION) - CMach_StructLayoutInitOffset(0); - - if (IS_TYPE_BITFIELD(member->type)) - member->offset = CMach_StructLayoutBitfield(TYPE_BITFIELD(member->type), member->qual); - else - member->offset = CMach_StructLayoutGetOffset(member->type, member->qual); - - if (tstruct->stype == STRUCT_TYPE_UNION) { - tmp = CMach_StructLayoutGetCurSize(); - if (tmp > r28) - r28 = tmp; - } - - if (member->name == no_name_node) - r23 = 1; - - if (!member->name) { - CError_ASSERT(4064, IS_TYPE_STRUCT(member->type)); - innerbase = member->offset; - innermember = TYPE_STRUCT(member->type)->members; - r23 = 1; - while (innermember) { - if (ismember(tstruct, innermember->name)) - CError_Error(CErrorStr133, innermember->name->name); - if (r23) { - member->type = innermember->type; - member->name = innermember->name; - member->qual = innermember->qual; - member->offset = innerbase + innermember->offset; - } else { - newmember = galloc(sizeof(StructMember)); - memclrw(newmember, sizeof(StructMember)); - newmember->next = member->next; - newmember->type = innermember->type; - newmember->name = innermember->name; - newmember->qual = innermember->qual | Q_WEAK; - newmember->offset = innerbase + innermember->offset; - member->next = newmember; - member = newmember; - } - if (copts.reverse_bitfields && IS_TYPE_BITFIELD(member->type)) { - bf = galloc(sizeof(TypeBitfield)); - *bf = *TYPE_BITFIELD(member->type); - CABI_ReverseBitField(bf); - member->type = TYPE(bf); - } - r23 = 0; - innermember = innermember->next; - } - r23 = 1; - } - } - - if (r23) { - memberp = &tstruct->members; - while (*memberp) { - if ((*memberp)->name == no_name_node || !(*memberp)->name) - *memberp = (*memberp)->next; - else - memberp = &(*memberp)->next; - } - } - - if (tstruct->stype == STRUCT_TYPE_UNION) - r24 = r28; - else - r24 = CMach_StructLayoutGetCurSize(); - tstruct->size = r24; - tstruct->align = CMach_GetStructAlign(tstruct); - tstruct->size = r24 + CABI_StructSizeAlignValue(TYPE(tstruct), r24); - - if (copts.reverse_bitfields) { - for (member = tstruct->members; member; member = member->next) { - if (IS_TYPE_BITFIELD(member->type)) - CABI_ReverseBitField(TYPE_BITFIELD(member->type)); - } - } - - if (copts.warn_padding && tstruct->stype != STRUCT_TYPE_UNION) { - StructMember *prev; - - member = tstruct->members; - prev = NULL; - while (member) { - if (prev && (prev->offset + prev->type->size) < member->offset) { - CError_Warning(CErrorStr350, member->offset - (prev->offset + prev->type->size), prev->name->name); - } - prev = member; - member = member->next; - } - - if (prev && (prev->offset + prev->type->size) < tstruct->size) { - CError_Warning(CErrorStr350, tstruct->size - (prev->offset + prev->type->size), prev->name->name); - } - } -} - -static SInt32 scanstructdeclarationlist(TypeStruct *tstruct, Boolean flag) { - SInt32 offset; - StructMember *member; - BigDeclInfo bde; - - offset = -1; - memclrw(&bde, sizeof(BigDeclInfo)); - - if (tk == TK_AT_DEFS) { - CPrep_NewFileOffsetInfo(&member_fileoffset, NULL); - CObjC_ParseDefs(tstruct); - if ((tk = lex()) != '}') - CError_Error(CErrorStr130); - } else { - do { - CPrep_NewFileOffsetInfo(&member_fileoffset, NULL); - memclrw(&bde.declinfo, sizeof(DeclInfo)); - CParser_GetDeclSpecs(&bde.declinfo, 0); - if (bde.declinfo.storageclass || bde.declinfo.x44) { - CError_Error(CErrorStr131); - tstruct->members = NULL; - return -1; - } - - if (tk != ';') { - while (1) { - CDecl_ScanStructDeclarator(&bde); - if (!CanCreateObject(bde.declinfo2.thetype)) { - CError_Error(CErrorStr131); - bde.xCD = 0; - } - - if (bde.declinfo2.operator_token) { - CError_Error(CErrorStr131); - bde.xCD = 0; - } - - if (bde.xCD) { - if (bde.declinfo2.name == no_name_node || !ismember(tstruct, bde.declinfo2.name)) { - member = galloc(sizeof(StructMember)); - memclrw(member, sizeof(StructMember)); - member->type = bde.declinfo2.thetype; - member->name = bde.declinfo2.name; - member->qual = bde.declinfo2.qual; - appendmember(tstruct, member); - - if (flag) { - CBrowse_AddStructMember(member, CPrep_BrowserTokenOffset(&member_fileoffset) + 1, CPrep_BrowserFileOffset()); - } - } else { - CError_Error(CErrorStr133, bde.declinfo2.name->name); - } - } - - if (tk != ',') - break; - tk = lex(); - } - } else if (!copts.ANSIstrict && IS_TYPE_STRUCT(bde.declinfo.thetype)) { - member = galloc(sizeof(StructMember)); - memclrw(member, sizeof(StructMember)); - member->type = bde.declinfo.thetype; - appendmember(tstruct, member); - } else { - CError_Error(CErrorStr131); - } - - if (tk != ';') { - tstruct->members = NULL; - CError_Error(CErrorStr123); - return -1; - } - - CPrep_TokenStreamFlush(); - } while ((tk = lex()) != '}'); - CDecl_LayoutStruct(tstruct); - } - - if (flag) { - offset = CPrep_BrowserFileOffset(); - if (tk == ';') - offset++; - } - - tk = lex(); - return offset; -} - -static TypeStruct *CDecl_DefineStruct(HashNameNode *name, short stype) { - TypeStruct *tstruct; - - tstruct = galloc(sizeof(TypeStruct)); - memclrw(tstruct, sizeof(TypeStruct)); - - tstruct->type = TYPESTRUCT; - tstruct->align = 1; - tstruct->stype = stype; - if (name) { - tstruct->name = name; - CScope_DefineTypeTag((in_func_arglist && !copts.cplusplus) ? cscope_root : cscope_current, name, (Type *) tstruct); - } - - return tstruct; -} - -void scanstruct(DeclInfo *declinfo, short structtype) { - Type *type; - HashNameNode *name; - TypeStruct typecopy; - Boolean add_to_browse; - GList gl; - SInt32 offset; - - if (copts.cplusplus) { - CDecl_ParseClass(declinfo, structtype, 1, 0); - return; - } - - if (tk == TK_IDENTIFIER) { - name = tkidentifier; - type = CScope_GetTagType(cscope_current, name); - if (type) { - if (IS_TYPE_CLASS(type)) { - CDecl_ParseClass(declinfo, structtype, 1, 0); - return; - } - - tk = lex(); - if (!CScope_GetLocalTagType(cscope_current, name) && (tk == ';' || tk == '{')) - type = (Type *) CDecl_DefineStruct(name, structtype); - - if (!IS_TYPE_STRUCT(type) || TYPE_STRUCT(type)->stype != structtype) { - CError_Error(CErrorStr132, name->name); - declinfo->thetype = type; - return; - } - - if (tk != '{') { - declinfo->thetype = type; - return; - } - - if (type->size) { - CError_Error(CErrorStr132, name->name); - type = (Type *) CDecl_DefineStruct(NULL, structtype); - } - } else { - type = (Type *) CDecl_DefineStruct(name, structtype); - if ((tk = lex()) != '{') { - declinfo->thetype = type; - return; - } - } - } else if (tk != '{') { - CError_Error(CErrorStr131); - declinfo->thetype = (Type *) &stsignedint; - return; - } else { - type = (Type *) CDecl_DefineStruct(NULL, structtype); - } - - if ((add_to_browse = cparamblkptr->browseoptions.recordClasses && declinfo->file->recordbrowseinfo)) - CBrowse_BeginStruct(declinfo, TYPE_STRUCT(type), &gl); - - typecopy = *TYPE_STRUCT(type); - tk = lex(); - offset = scanstructdeclarationlist(&typecopy, add_to_browse); - *TYPE_STRUCT(type) = typecopy; - declinfo->thetype = type; - - if (add_to_browse) - CBrowse_EndStruct(offset, &gl); -} - -static void InlineFunctionObject(Object *obj, TypeClass *tclass) { - TokenStream stream; - CPrepFileInfo *file; - - obj->qual |= Q_INLINE; - TYPE_FUNC(obj->type)->flags |= FUNC_DEFINED; - - CPrep_StreamGetBlock(&stream, NULL, 1); - if (stream.tokens) { - if (IS_TYPEFUNC_METHOD(TYPE_FUNC(obj->type)) && (TYPE_METHOD(obj->type)->theclass->flags & CLASS_IS_TEMPL)) { - TYPE_FUNC(obj->type)->flags |= FUNC_IS_TEMPL_INSTANCE; - CTemplClass_DefineMember(TEMPL_CLASS(TYPE_METHOD(obj->type)->theclass), obj, &member_fileoffset, &stream); - } else { - CInline_AddInlineFunctionAction(obj, tclass, &member_fileoffset, &stream, 0); - } - } - - file = CPrep_BrowserCurrentFile(); - if (file->recordbrowseinfo) { - CBrowse_NewFunction( - obj, file, - member_fileoffset.file, - CPrep_BrowserTokenOffset(&member_fileoffset) + 1, - CPrep_BrowserFileOffset()); - } - - if (lookahead() == ';') - tk = lex(); - else - tk = ';'; -} - -void CDecl_ExtractClassExportFlags(DeclInfo *declinfo, UInt8 flags) { - if (flags & CLASS_EFLAGS_INTERNAL) - declinfo->exportflags = declinfo->exportflags | EXPORT_FLAGS_INTERNAL; - if (flags & CLASS_EFLAGS_IMPORT) - declinfo->exportflags = declinfo->exportflags | EXPORT_FLAGS_IMPORT; - if (flags & CLASS_EFLAGS_EXPORT) - declinfo->exportflags = declinfo->exportflags | EXPORT_FLAGS_EXPORT; -} - -TypeMemberFunc *CDecl_MakeTypeMemberFunc(TypeFunc *tfunc, TypeClass *tclass, Boolean flag) { - TypeMemberFunc *method; - - method = galloc(sizeof(TypeMemberFunc)); - memclrw(method, sizeof(TypeMemberFunc)); - *TYPE_FUNC(method) = *tfunc; - method->theclass = tclass; - method->is_static = flag; - method->flags |= FUNC_METHOD; - if (!flag) - CDecl_AddThisPointerArgument(TYPE_FUNC(method), tclass); - - if ((flag || (tfunc->flags & (FUNC_IS_CTOR | FUNC_IS_DTOR))) && (tfunc->flags & (FUNC_CONST | FUNC_VOLATILE))) - CError_Error(CErrorStr384); - - return method; -} - -static void CDecl_MakeFunctionVirtual(TypeClass *tclass, Object *func) { - if (is_pascal_object(func)) - CError_Error(CErrorStr219); - if (tclass->mode == CLASS_MODE_UNION) - CError_Error(CErrorStr352, func); - func->datatype = DVFUNC; -} - -static void CDecl_AddFunctionMember(ClassLayout *decle, TypeClass *tclass, DeclInfo *declinfo, AccessType access, Boolean flag1, Boolean flag2, Boolean flag3, Boolean flag4) { - NameSpaceObjectList *list; // r20 - Object *obj; // also r20 - TypeMemberFunc *tfunc; // r19 - Boolean r31; - Boolean outflag; - - if (IS_TYPE_ARRAY(TYPE_FUNC(declinfo->thetype)->functype) || IS_TYPE_FUNC(TYPE_FUNC(declinfo->thetype)->functype)) { - CError_Error(CErrorStr128); - TYPE_FUNC(declinfo->thetype)->functype = (Type *) &stsignedint; - } - - if (tclass->sominfo) - CSOM_CheckFuncType(TYPE_FUNC(declinfo->thetype)); - - r31 = 0; - if (declinfo->qual & Q_VIRTUAL) { - declinfo->qual &= ~Q_VIRTUAL; - r31 = 1; - flag1 = 1; - } - - if ((list = CScope_FindName(tclass->nspace, declinfo->name))) { - if (list->object->otype != OT_TYPETAG) { - if (list->object->otype != OT_OBJECT || !IS_TYPE_FUNC(OBJECT(list->object)->type)) - CError_Error(CErrorStr133, declinfo->name->name); - } else { - list = NULL; - } - } - - if (!IS_TYPEFUNC_METHOD(TYPE_FUNC(declinfo->thetype))) { - tfunc = CDecl_MakeTypeMemberFunc(TYPE_FUNC(declinfo->thetype), tclass, flag4); - declinfo->thetype = (Type *) tfunc; - } else { - tfunc = TYPE_METHOD(declinfo->thetype); - CError_ASSERT(4579, !tclass->sominfo); - } - - CDecl_ExtractClassExportFlags(declinfo, tclass->eflags); - - CError_ASSERT(4597, cscope_current == tclass->nspace); - - if (list) { - obj = CDecl_OverloadFunctionObject(list, declinfo, &outflag, flag4 ? OverloadMode1 : OverloadMode2, 0); - if (!obj) - return; - if (outflag) - tfunc->vtbl_index = ++decle->lex_order_count; - else - CError_Error(CErrorStr133, CError_GetObjectName(obj)); - } else { - tfunc->vtbl_index = ++decle->lex_order_count; - obj = CParser_NewFunctionObject(declinfo); - if ((tclass->flags & CLASS_IS_TEMPL) && CTemplTool_IsTemplateArgumentDependentType(declinfo->thetype)) - CTemplClass_RegisterObjectDef(TEMPL_CLASS(tclass), OBJ_BASE(obj)); - CScope_AddObject(tclass->nspace, declinfo->name, OBJ_BASE(obj)); - } - - obj->access = access; - CheckDefaultArgs(TYPE_FUNC(obj->type)->args); - - if (flag2) { - tfunc->flags |= FUNC_CONVERSION; - tclass->flags = tclass->flags | CLASS_IS_CONVERTIBLE; - } - - if (r31) { - CDecl_MakeFunctionVirtual(tclass, obj); - decle->has_vtable = 1; - } - - if ((flag1 || r31) && flag3 && (tk == '=')) { - if ((tk = lex()) == TK_INTCONST) { - if (!CInt64_IsZero(&tkintconst)) - CError_Error(CErrorStr121); - tfunc->flags |= FUNC_PURE; - tclass->flags = tclass->flags | CLASS_ABSTRACT; - tk = lex(); - } else { - CError_Error(CErrorStr121); - } - } - - if (flag3 && ((tk == '{') || (tk == TK_TRY) || ((tk == ':') && CClass_IsConstructor(obj)))) { - if (declinfo->x49) - CError_Error(CErrorStr127); - InlineFunctionObject(obj, NULL); - } - - if (cparamblkptr->browseoptions.recordClasses) - CBrowse_AddClassMemberFunction(obj, CPrep_BrowserTokenOffset(&member_fileoffset) + 1, CPrep_BrowserFileOffset()); -} - -static Boolean CDecl_IsAccessDeclaration(TypeClass *tclass, AccessType access) { - SInt32 state; - Boolean flag; - - CPrep_TokenStreamGetState(&state); - flag = 0; - -restart: - switch (tk) { - case TK_IDENTIFIER: - if ((tk = lex()) != ';') - break; - case TK_OPERATOR: - CPrep_TokenStreamSetCurState(&state); - if (flag) { - CScope_ParseUsingDeclaration(tclass->nspace, access, 1); - return 1; - } - return 0; - default: - CPrep_TokenStreamSetCurState(&state); - return 0; - } - - switch (tk) { - case TK_COLON_COLON: - flag = 1; - tk = lex(); - goto restart; - case '<': - tk = lex(); - while (1) { - switch (tk) { - case 0: - case ';': - case '{': - case '}': - CPrep_TokenStreamSetCurState(&state); - return 0; - case '>': - if ((tk = lex()) == TK_COLON_COLON) { - flag = 1; - tk = lex(); - goto restart; - } - default: - tk = lex(); - } - } - } - - CPrep_TokenStreamSetCurState(&state); - return 0; -} - -void CDecl_PackDeclInfo(PackedDeclInfo *packed, DeclInfo *declinfo) { - packed->thetype = declinfo->thetype; - packed->qual = declinfo->qual; - packed->nspace = declinfo->nspace; - packed->name = declinfo->name; - packed->expltargs = CTemplTool_MakeGlobalTemplArgCopy(declinfo->expltargs); - packed->storageclass = declinfo->storageclass; - packed->section = declinfo->section; - packed->exportflags = declinfo->exportflags; - packed->has_expltargs = declinfo->has_expltargs; -} - -void CDecl_UnpackDeclInfo(DeclInfo *declinfo, PackedDeclInfo *packed) { - memclrw(declinfo, sizeof(DeclInfo)); - declinfo->thetype = packed->thetype; - declinfo->qual = packed->qual; - declinfo->nspace = packed->nspace; - declinfo->name = packed->name; - declinfo->expltargs = packed->expltargs; - declinfo->storageclass = packed->storageclass; - declinfo->section = packed->section; - declinfo->exportflags = packed->exportflags; - declinfo->has_expltargs = packed->has_expltargs; -} - -void CDecl_AddFriend(TypeClass *tclass, Object *friendfunc, TypeClass *friendclass) { - ClassFriend *scan; - ClassFriend *newfriend; - - if (friendfunc) { - for (scan = tclass->friends; scan; scan = scan->next) { - if (!scan->isclass && scan->u.obj == friendfunc) - break; - } - if (!scan) { - newfriend = galloc(sizeof(ClassFriend)); - memclrw(newfriend, sizeof(ClassFriend)); - newfriend->next = tclass->friends; - tclass->friends = newfriend; - newfriend->u.obj = friendfunc; - newfriend->isclass = 0; - } - } - - if (friendclass) { - for (scan = tclass->friends; scan; scan = scan->next) { - if (scan->isclass && scan->u.theclass == friendclass) - break; - } - if (!scan) { - newfriend = galloc(sizeof(ClassFriend)); - memclrw(newfriend, sizeof(ClassFriend)); - newfriend->next = tclass->friends; - tclass->friends = newfriend; - newfriend->u.theclass = friendclass; - newfriend->isclass = 1; - } - } -} - -static void CDecl_ParseFriendDecl(TypeClass *tclass) { - DeclInfo declinfo; - DeclInfo declinfo_copy; - Boolean is_templ; - Boolean r27; - Boolean pflag; - CScopeSave save; - Object *obj; - NameSpace *nspace; - - is_templ = (tclass->flags & CLASS_IS_TEMPL) != 0; - r27 = (tk == TK_CLASS || tk == TK_STRUCT || tk == TK_UNION); - memclrw(&declinfo, sizeof(DeclInfo)); - - declinfo.in_friend_decl = 1; - CParser_GetDeclSpecs(&declinfo, 1); - if (declinfo.storageclass) { - CError_Error(CErrorStr177); - declinfo.storageclass = 0; - } - declinfo.in_friend_decl = 0; - - if (tk == ';') { - if (!r27) - CError_Error(CErrorStr201); - - if (IS_TYPE_CLASS(declinfo.thetype)) { - if (!(TYPE_CLASS(declinfo.thetype)->flags & CLASS_IS_TEMPL) || CParser_CheckTemplateClassUsage(TEMPL_CLASS(declinfo.thetype), 1)) { - if (!is_templ) - CDecl_AddFriend(tclass, NULL, TYPE_CLASS(declinfo.thetype)); - else - CTemplClass_RegisterFriend(TEMPL_CLASS(tclass), &declinfo); - } - } else { - if (IS_TYPE_TEMPLATE(declinfo.thetype) && is_templ) - CTemplClass_RegisterFriend(TEMPL_CLASS(tclass), &declinfo); - else - CError_Error(CErrorStr201); - } - } else { - if (declinfo.x14 || declinfo.x10) { - CDecl_ParseSpecialMember(&declinfo, 0); - if (declinfo.name) { - obj = CDecl_GetFunctionObject(&declinfo, NULL, &pflag, 0); - if (obj) - CDecl_AddFriend(tclass, obj, NULL); - if (tk != ';') - CError_Error(CErrorStr123); - else - tk = lex(); - } - return; - } else { - nspace = CScope_FindGlobalNS(cscope_current); - declinfo_copy = declinfo; - while (1) { - declinfo = declinfo_copy; - declinfo.x4D = 1; - declinfo.x51 = 1; - scandeclarator(&declinfo); - - if (IS_TYPE_FUNC(declinfo.thetype)) { - if (!is_templ) { - CScope_SetNameSpaceScope(nspace, &save); - obj = CDecl_GetFunctionObject(&declinfo, NULL, &pflag, 0); - CScope_RestoreScope(&save); - - if (obj) { - CDecl_AddFriend(tclass, obj, NULL); - if (!declinfo.nspace && tk == '{') { - InlineFunctionObject(obj, tclass); - } else { - if (!obj->sclass) - obj->sclass = TK_EXTERN; - } - } - } else { - CTemplClass_RegisterFriend(TEMPL_CLASS(tclass), &declinfo); - } - } else { - CError_Error(CErrorStr201); - } - - if (tk != ',') - break; - tk = lex(); - } - } - } - - if (tk == ';') - tk = lex(); - else - CError_Error(CErrorStr123); -} - -static ObjMemberVar *CDecl_InstanceDataDeclarator(ClassLayout *decle, TypeClass *tclass, Type *type, UInt32 qual, HashNameNode *name, AccessType access) { - NameSpaceObjectList *list; - ObjMemberVar *ivar; - ObjMemberVar *scan; - - if (name && (list = CScope_FindName(tclass->nspace, name))) { - switch (list->object->otype) { - case OT_NAMESPACE: - CError_Error(CErrorStr321); - return NULL; - case OT_ENUMCONST: - case OT_TYPE: - case OT_OBJECT: - CError_Error(CErrorStr322); - return NULL; - case OT_MEMBERVAR: - CError_Error(CErrorStr122, name->name); - return NULL; - case OT_TYPETAG: - break; - default: - CError_FATAL(4989); - } - } - - ivar = galloc(sizeof(ObjMemberVar)); - memclrw(ivar, sizeof(ObjMemberVar)); - ivar->otype = OT_MEMBERVAR; - ivar->access = access; - ivar->name = name; - ivar->type = type; - ivar->qual = qual; - if (!tclass->sominfo) - decle->lex_order_count++; - - if ((scan = tclass->ivars)) { - while (scan->next) - scan = scan->next; - scan->next = ivar; - } else { - tclass->ivars = ivar; - } - - if (name && name != no_name_node) { - CScope_AddObject(tclass->nspace, name, OBJ_BASE(ivar)); - if ((tclass->flags & CLASS_IS_TEMPL) && CTemplTool_IsTemplateArgumentDependentType(type)) - CTemplClass_RegisterObjectDef(TEMPL_CLASS(tclass), OBJ_BASE(ivar)); - if (cparamblkptr->browseoptions.recordClasses) - CBrowse_AddClassMemberVar(ivar, CPrep_BrowserTokenOffset(&member_fileoffset) + 1, CPrep_BrowserFileOffset()); - } - - return ivar; -} - -void CDecl_CheckCtorIntegrity(FuncArg *args, TypeClass *tclass) { - if (args && args->type == TYPE(tclass)) { - if (!args->next || args->next->dexpr) { - CError_Error(CErrorStr239); - args->type = &stvoid; - } - } -} - -static void CDecl_ParseClassMembers(ClassLayout *decle, TypeClass *tclass, short mode) { - AccessType access; - Boolean r17; - BigDeclInfo bde; - DeclInfo declinfo; - //Type *newtype - ObjMemberVar *ivar; - ObjMemberVar *scanivar; - Type *tmptype; - UInt32 r22; - UInt32 r21; - UInt8 r20; - UInt8 r18; - Boolean r19; - short t; - - r17 = (tclass->flags & CLASS_IS_TEMPL) && TEMPL_CLASS(tclass)->pspec_owner; - memclrw(&bde, sizeof(BigDeclInfo)); - - access = (mode == CLASS_MODE_CLASS) ? ACCESSPRIVATE : ACCESSPUBLIC; - global_access = access; - - restart: - while (tk != '}') { - CPrep_NewFileOffsetInfo(&member_fileoffset, NULL); - r21 = 0; - r22 = 0; - r20 = 0; - r18 = 0; - - if (tk == TK_TEMPLATE) { - NameSpace *nspace = cscope_current; - TemplClass *tmclass; - - if (nspace->theclass && (nspace->theclass->flags & CLASS_IS_TEMPL)) { - tmclass = TEMPL_CLASS(nspace->theclass); - } else { - for (; nspace; nspace = nspace->parent) { - if (!nspace->name && !nspace->theclass && nspace->parent && !nspace->is_templ) { - CError_Error(CErrorStr347); - break; - } - } - } - - CTempl_Parse(TEMPL_CLASS(tclass), access); - tk = lex(); - continue; - } - - restart2: - r19 = 0; - switch (tk) { - case TK_UU_DECLSPEC: - if ((tk = lex()) != '(') - CError_Error(CErrorStr114); - memclrw(&declinfo, sizeof(DeclInfo)); - CParser_ParseDeclSpec(&declinfo, 1); - r21 |= declinfo.qual; - r20 |= declinfo.exportflags; - r18 = declinfo.section; - if ((tk = lex()) != ')') - CError_Error(CErrorStr115); - tk = lex(); - goto restart2; - case TK_PRIVATE: - global_access = access = ACCESSPRIVATE; - goto check_access; - case TK_PROTECTED: - global_access = access = ACCESSPROTECTED; - goto check_access; - case TK_PUBLIC: - global_access = access = ACCESSPUBLIC; - check_access: - if (r22 || r20) - CError_Error(CErrorStr121); - if ((tk = lex()) != ':') - CError_Error(CErrorStr170); - else - tk = lex(); - goto restart; - case TK_EXPLICIT: - CError_QualifierCheck(r22 & Q_EXPLICIT); - r22 |= Q_EXPLICIT; - tk = lex(); - goto restart2; - case TK_INLINE: - CError_QualifierCheck(r22 & Q_INLINE); - r22 |= Q_INLINE; - tk = lex(); - goto restart2; - case TK_ASM: - CError_QualifierCheck(r22 & Q_ASM); - r22 |= Q_ASM; - tk = lex(); - goto restart2; - case TK_VIRTUAL: - CError_QualifierCheck(r22 & Q_VIRTUAL); - r22 |= Q_VIRTUAL; - tk = lex(); - goto restart2; - case TK_IDENTIFIER: - while (1) { - if (tkidentifier == tclass->classname) { - t = lookahead(); - tkidentifier = tclass->classname; - r19 = 1; - if (copts.cpp_extensions && t == TK_COLON_COLON) { - lex(); - tk = lex(); - if (tk == TK_IDENTIFIER) - continue; - if (tk == '~') - goto restart2; - CError_Error(CErrorStr107); - } - - if (t == '(') { - redo_thing: - CError_QualifierCheck(r22 & ~(Q_EXPLICIT | Q_INLINE | Q_ASM)); - memclrw(&bde.declinfo2, sizeof(DeclInfo)); - if (tclass->sominfo) - bde.declinfo2.thetype = &stvoid; - else - bde.declinfo2.thetype = TYPE(&void_ptr); - - bde.declinfo2.qual = r22; - bde.declinfo2.exportflags = r20; - bde.declinfo2.section = r18; - bde.declinfo2.x4B = 1; - scandeclarator(&bde.declinfo2); - if (IS_TYPE_FUNC(bde.declinfo2.thetype)) { - if (r17) - bde.declinfo2.thetype = CTemplTool_ResolveMemberSelfRefs(TEMPL_CLASS(tclass), bde.declinfo2.thetype, &bde.declinfo2.qual); - if (tclass->sominfo) { - if (TYPE_FUNC(bde.declinfo2.thetype)->args) - CError_Error(CErrorStr272); - bde.declinfo2.qual |= Q_VIRTUAL; - } else { - CDecl_CheckCtorIntegrity(TYPE_FUNC(bde.declinfo2.thetype)->args, tclass); - if (tclass->flags & CLASS_HAS_VBASES) - CDecl_AddArgument(TYPE_FUNC(bde.declinfo2.thetype), TYPE(&stsignedshort)); - bde.declinfo2.qual &= ~Q_VIRTUAL; - } - TYPE_FUNC(bde.declinfo2.thetype)->flags |= FUNC_IS_CTOR; - bde.declinfo2.name = constructor_name_node; - bde.declinfo2.qual |= r21; - CDecl_AddFunctionMember(decle, tclass, &bde.declinfo2, access, 0, 0, 1, 0); - } else { - CError_Error(CErrorStr241); - } - if (tk == ';') - tk = lex(); - else - CError_Error(CErrorStr123); - goto restart; - } - } - // 6F8D8 - if (!r22 && CDecl_IsAccessDeclaration(tclass, access)) { - tk = lex(); - goto restart; - } - break; - } - break; - case TK_USING: - CError_QualifierCheck(r22); - tk = lex(); - CScope_ParseUsingDeclaration(tclass->nspace, access, 0); - tk = lex(); - goto restart; - case '~': - if ((tk = lex()) != TK_IDENTIFIER || tkidentifier != tclass->classname) { - CError_Error(CErrorStr241); - goto restart; - } - CError_QualifierCheck(r22 & ~(Q_VIRTUAL | Q_INLINE | Q_ASM)); - if (tclass->flags & CLASS_IS_TEMPL_ANY) { - t = lookahead(); - tkidentifier = tclass->classname; - if (t == '<') { - memclrw(&bde.declinfo, sizeof(DeclInfo)); - CParser_GetDeclSpecs(&bde.declinfo, 0); - if (tk != '(' || bde.declinfo.thetype != TYPE(tclass) || bde.declinfo.nspace) { - CError_Error(CErrorStr241); - goto restart; - } - CPrep_UnLex(); - tk = TK_IDENTIFIER; - tkidentifier = tclass->classname; - } - } - memclrw(&bde.declinfo2, sizeof(DeclInfo)); - bde.declinfo2.qual = r22; - bde.declinfo2.exportflags = r20; - bde.declinfo2.section = r18; - if (tclass->sominfo) - bde.declinfo2.thetype = &stvoid; - else - bde.declinfo2.thetype = TYPE(&void_ptr); - scandeclarator(&bde.declinfo2); - if (IS_TYPE_FUNC(bde.declinfo2.thetype) && !TYPE_FUNC(bde.declinfo2.thetype)->args) { - if (!CScope_FindName(tclass->nspace, destructor_name_node)) { - if (tclass->sominfo) - bde.declinfo2.qual |= Q_VIRTUAL; - else - CDecl_AddArgument(TYPE_FUNC(bde.declinfo2.thetype), TYPE(&stsignedshort)); - bde.declinfo2.name = destructor_name_node; - TYPE_FUNC(bde.declinfo2.thetype)->flags |= FUNC_IS_DTOR; - bde.declinfo2.qual |= r21; - CDecl_AddFunctionMember(decle, tclass, &bde.declinfo2, access, 1, 0, 1, 0); - } else { - CError_Error(CErrorStr133, CError_GetFunctionName(tclass->nspace, destructor_name_node, NULL)); - } - } else { - CError_Error(CErrorStr146); - } - if (tk == ';') - tk = lex(); - else - CError_Error(CErrorStr123); - goto restart; - case TK_OPERATOR: - if (CMangler_OperatorName(lookahead())) { - memclrw(&bde.declinfo, sizeof(DeclInfo)); - bde.declinfo.thetype = TYPE(&stsignedint); - goto after_various_things; - } else { - tk = lex(); - CError_QualifierCheck(r22 & ~(Q_VIRTUAL | Q_INLINE | Q_ASM)); - memclrw(&bde.declinfo2, sizeof(DeclInfo)); - bde.declinfo2.qual = r22; - bde.declinfo2.exportflags = r20; - bde.declinfo2.section = r18; - conversion_type_name(&bde.declinfo2); - bde.declinfo2.qual |= r21; - tmptype = bde.declinfo2.thetype; - CDecl_NewConvFuncType(&bde.declinfo2); - if ((tclass->flags & CLASS_IS_TEMPL) && CTemplTool_IsTemplateArgumentDependentType(tmptype)) - bde.declinfo2.name = CParser_GetUniqueName(); - CDecl_AddFunctionMember(decle, tclass, &bde.declinfo2, access, 1, 1, 1, 0); - if (tk == ';') - tk = lex(); - else - CError_Error(CErrorStr123); - goto restart; - } - case TK_FRIEND: - tk = lex(); - CDecl_ParseFriendDecl(tclass); - goto restart; - } - - CError_QualifierCheck(r22 & Q_EXPLICIT); - global_access = access; - memclrw(&bde.declinfo, sizeof(DeclInfo)); - bde.declinfo.qual = r22; - bde.declinfo.exportflags = r20; - bde.declinfo.section = r18; - CParser_GetDeclSpecs(&bde.declinfo, 0); - - if (r19 && tk == '(' && (tclass->flags & CLASS_IS_TEMPL_ANY) && bde.declinfo.thetype == TYPE(tclass) && !bde.declinfo.nspace) { - CPrep_UnLex(); - tk = TK_IDENTIFIER; - tkidentifier = tclass->classname; - r22 = bde.declinfo.qual; - goto redo_thing; - } - - after_various_things: - switch (bde.declinfo.storageclass) { - case 0: - case TK_STATIC: - case TK_TYPEDEF: - case TK_MUTABLE: - break; - default: - CError_Error(CErrorStr177); - bde.declinfo.storageclass = 0; - } - - if (tk != ';') { - while (1) { - CDecl_ScanStructDeclarator(&bde); - if (r17) - bde.declinfo2.thetype = CTemplTool_ResolveMemberSelfRefs(TEMPL_CLASS(tclass), bde.declinfo2.thetype, &bde.declinfo2.qual); - if (bde.declinfo2.nspace) - CError_Error(CErrorStr200); - if (bde.declinfo2.operator_token) { - if (bde.declinfo.storageclass == TK_MUTABLE) - CError_QualifierCheck(Q_MUTABLE); - r19 = 0; - switch (bde.declinfo2.operator_token) { - case TK_NEW: - case TK_NEW_ARRAY: - CError_QualifierCheck(bde.declinfo2.qual & Q_VIRTUAL); - r19 = 1; - break; - case TK_DELETE: - case TK_DELETE_ARRAY: - CError_QualifierCheck(bde.declinfo2.qual & Q_VIRTUAL); - r19 = 1; - break; - default: - if (bde.declinfo2.storageclass == TK_STATIC) - CError_Error(CErrorStr193); - if (tclass->sominfo) - CError_Error(CErrorStr193); - } - - bde.declinfo2.storageclass = 0; - if (IS_TYPE_FUNC(bde.declinfo2.thetype)) { - bde.declinfo2.qual |= r21; - CDecl_AddFunctionMember(decle, tclass, &bde.declinfo2, access, r19 == 0, 0, 1, r19); - CDecl_CheckOperatorType(&bde.declinfo2, 1); - if (tclass->sominfo) - CSOM_FixNewDeleteFunctype(TYPE_FUNC(bde.declinfo2.thetype)); - } else { - CError_Error(CErrorStr121); - } - } else if (bde.xCD) { - if (bde.declinfo2.name == constructor_name_node || bde.declinfo2.name == destructor_name_node) - CError_Error(CErrorStr241); - switch (bde.declinfo2.storageclass) { - case TK_TYPEDEF: - CError_QualifierCheck(bde.declinfo2.qual & Q_VIRTUAL); - CDecl_TypedefDeclarator(&bde.declinfo2); - break; - case TK_STATIC: - CError_QualifierCheck(bde.declinfo2.qual & Q_VIRTUAL); - if (tclass->sominfo) - CError_Error(CErrorStr271); - if (IS_TYPE_FUNC(bde.declinfo2.thetype)) { - bde.declinfo2.qual |= r21; - bde.declinfo2.storageclass = 0; - if (bde.declinfo2.name == tclass->classname) - CError_Error(CErrorStr241); - CDecl_AddFunctionMember(decle, tclass, &bde.declinfo2, access, 0, 0, 1, 1); - } else { - CDecl_ExtractClassExportFlags(&bde.declinfo2, tclass->eflags); - bde.declinfo2.storageclass = 0; - CDecl_DataDeclarator(&bde.declinfo2, access, 1); - } - break; - case 0: - case TK_MUTABLE: - if (IS_TYPE_FUNC(bde.declinfo2.thetype)) { - if (bde.declinfo2.name == tclass->classname) - CError_Error(CErrorStr241); - if (bde.declinfo.storageclass == TK_MUTABLE) - CError_QualifierCheck(Q_MUTABLE); - bde.declinfo2.qual |= r21; - CDecl_AddFunctionMember(decle, tclass, &bde.declinfo2, access, 1, 0, 1, 0); - } else { - CDecl_CompleteType(bde.declinfo2.thetype); - CanCreateObject(bde.declinfo2.thetype); - CError_QualifierCheck(bde.declinfo2.qual & (Q_VIRTUAL | Q_INLINE)); - if (bde.declinfo2.storageclass == TK_MUTABLE) - bde.declinfo2.qual |= Q_MUTABLE; - CDecl_InstanceDataDeclarator(decle, tclass, bde.declinfo2.thetype, bde.declinfo2.qual, bde.declinfo2.name, access); - } - break; - default: - CError_Error(CErrorStr177); - } - } - - // this should be 70058 - if (tk != ',') - break; // goes to 70148 - tk = lex(); - } - } else if (CParser_IsAnonymousUnion(&bde.declinfo, 1)) { - if ((ivar = CDecl_InstanceDataDeclarator(decle, tclass, bde.declinfo.thetype, 0, NULL, access))) - ivar->anonunion = 1; - for (scanivar = TYPE_CLASS(bde.declinfo.thetype)->ivars; scanivar; scanivar = scanivar->next) { - tmptype = scanivar->type; - if (IS_TYPE_BITFIELD(tmptype) && copts.reverse_bitfields) { - TypeBitfield *newtype = galloc(sizeof(TypeBitfield)); - *newtype = *TYPE_BITFIELD(tmptype); - CABI_ReverseBitField(newtype); - tmptype = TYPE(newtype); - } - if ((ivar = CDecl_InstanceDataDeclarator(decle, tclass, tmptype, scanivar->qual, scanivar->name, access))) - ivar->offset = scanivar->offset | 0x80000000; - } - } - - // this should be 70148 i think - if (tk != ';') { - CError_Error(CErrorStr123); - return; - } - CPrep_TokenStreamFlush(); - tk = lex(); - } -} - -static VClassList *AddVBaseToList(TypeClass *tclass, TypeClass *baseclass) { - VClassList *scan; - VClassList *vbase; - - for (scan = tclass->vbases; scan; scan = scan->next) { - if (scan->base == baseclass) - return NULL; - } - - vbase = galloc(sizeof(VClassList)); - memclrw(vbase, sizeof(VClassList)); - vbase->base = baseclass; - - if ((scan = tclass->vbases)) { - while (scan->next) - scan = scan->next; - scan->next = vbase; - } else { - tclass->vbases = vbase; - } - - return vbase; -} - -void CDecl_MakeVBaseList(TypeClass *tclass) { - ClassList *base; - VClassList *vbase; - VClassList *new_vbase; - SInt32 offset; - - if (copts.vbase_ctor_offset) - tclass->flags = tclass->flags | CLASS_FLAGS_8000; - - for (base = tclass->bases, offset = tclass->size; base; base = base->next) { - for (vbase = base->base->vbases; vbase; vbase = vbase->next) { - if ((new_vbase = AddVBaseToList(tclass, vbase->base))) { - new_vbase->offset = offset + CMach_MemberAlignValue(TYPE(vbase->base), offset); - offset = new_vbase->offset + vbase->base->size; - } - } - - if (base->is_virtual && (new_vbase = AddVBaseToList(tclass, base->base))) { - new_vbase->offset = offset + CMach_MemberAlignValue(TYPE(base->base), offset); - offset = new_vbase->offset + base->base->size; - } - } -} - -Boolean CDecl_CheckNewBase(TypeClass *tclass, TypeClass *baseclass, Boolean is_virtual) { - ClassList *scan; - - if (tclass == baseclass) { - CError_Error(CErrorStr131); - return 0; - } - - if (!(baseclass->flags & CLASS_COMPLETED)) { - CError_Error(CErrorStr136, baseclass, 0); - return 0; - } - - if (baseclass->flags & CLASS_SINGLE_OBJECT) { - if (is_virtual || tclass->bases) { - CError_Error(CErrorStr191); - return 0; - } - tclass->flags = tclass->flags | CLASS_SINGLE_OBJECT; - } - - if (baseclass->flags & CLASS_HANDLEOBJECT) { - if (is_virtual || tclass->bases) { - CError_Error(CErrorStr191); - return 0; - } - tclass->flags = tclass->flags | CLASS_HANDLEOBJECT; - } - - if (baseclass->sominfo) { - if (!is_virtual) - CError_Error(CErrorStr268); - CSOM_MakeSOMClass(tclass); - } else if (tclass->sominfo) { - CError_Error(CErrorStr267); - } - - if (tclass->bases && (tclass->flags & CLASS_SINGLE_OBJECT) && (tclass->flags & CLASS_SINGLE_OBJECT)) { - CError_Error(CErrorStr131); - return 0; - } - - if (copts.ecplusplus && (is_virtual || tclass->bases)) { - CError_Error(CErrorStr339); - return 0; - } - - for (scan = tclass->bases; scan; scan = scan->next) { - if (scan->base == baseclass) { - CError_Error(CErrorStr131); - return 0; - } - } - - if (baseclass->flags & CLASS_COM_OBJECT) - tclass->flags = tclass->flags | CLASS_COM_OBJECT; - if (baseclass->flags & CLASS_IS_CONVERTIBLE) - tclass->flags = tclass->flags | CLASS_IS_CONVERTIBLE; - if (baseclass->flags & CLASS_HAS_VBASES) - tclass->flags = tclass->flags | CLASS_HAS_VBASES; - - if (is_virtual) - tclass->flags = tclass->flags | CLASS_HAS_VBASES; - - return 1; -} - -static void CDecl_ParseBaseClassList(TypeClass *tclass, short mode, Boolean is_templ) { - Boolean is_virtual; - AccessType access; - NameResult pr; - ObjType *inherited_type; - ClassList *base; - ClassList *scan; - TypeClass *baseclass; - - do { - if (mode == CLASS_MODE_CLASS) - access = ACCESSPRIVATE; - else - access = ACCESSPUBLIC; - - is_virtual = 0; - if ((tk = lex()) == TK_VIRTUAL) { - tk = lex(); - is_virtual = 1; - } - - switch (tk) { - case TK_PRIVATE: - access = ACCESSPRIVATE; - tk = lex(); - break; - case TK_PUBLIC: - access = ACCESSPUBLIC; - tk = lex(); - break; - case TK_PROTECTED: - if (!copts.ARMconform) { - access = ACCESSPROTECTED; - tk = lex(); - } - break; - } - - if (tk == TK_VIRTUAL) { - if (is_virtual) - CError_Error(CErrorStr121); - is_virtual = 1; - tk = lex(); - } - - if (CScope_ParseDeclName(&pr)) { - if (!pr.type) { - if (!pr.name_4) { - CError_Error(CErrorStr121); - } else if (tk == TK_IDENTIFIER && pr.name_4 == tkidentifier) { - goto special_parsing; - } - CError_Error(CErrorStr140, tkidentifier->name); - continue; - } - - CDecl_CompleteType(pr.type); - if (is_templ && CTemplTool_IsTemplateArgumentDependentType(pr.type)) { - if (!IS_TYPE_CLASS(pr.type) || !(TYPE_CLASS(pr.type)->flags & CLASS_IS_TEMPL) || - CParser_CheckTemplateClassUsage(TEMPL_CLASS(pr.type), 1)) { - CTemplClass_RegisterBaseClass(TEMPL_CLASS(tclass), pr.type, access, is_virtual); - if (is_virtual) - tclass->flags = tclass->flags | CLASS_HAS_VBASES; - } - continue; - } - - if (!IS_TYPE_CLASS(pr.type) || (TYPE_CLASS(pr.type)->flags & CLASS_IS_TEMPL)) { - CError_Error(CErrorStr131); - continue; - } - baseclass = TYPE_CLASS(pr.type); - } else { - special_parsing: - if (!strcmp(tkidentifier->name, "HandleObject")) { - if (tclass->bases) - CError_Error(CErrorStr191); - tclass->flags |= CLASS_SINGLE_OBJECT | CLASS_HANDLEOBJECT; - tk = lex(); - break; - } - if (!strcmp(tkidentifier->name, "SingleObject") || !strcmp(tkidentifier->name, "SingleInheritance")) { - if (tclass->bases) - CError_Error(CErrorStr191); - tclass->flags = tclass->flags | CLASS_SINGLE_OBJECT; - tk = lex(); - break; - } - if (!strcmp(tkidentifier->name, "__comobject")) { - tclass->flags = tclass->flags | CLASS_COM_OBJECT; - tk = lex(); - break; - } - if (!strcmp(tkidentifier->name, "__somobject")) { - if (!is_virtual) - CError_Error(CErrorStr268); - CSOM_MakeSOMClass(tclass); - tk = lex(); - break; - } - if (!strcmp(tkidentifier->name, "__javaobject")) { - tk = lex(); - tclass->action = CLASS_ACTION_3; - break; - } - - CError_Error(CErrorStr140, tkidentifier->name); - continue; - } - - if (CDecl_CheckNewBase(tclass, baseclass, is_virtual)) { - base = galloc(sizeof(ClassList)); - memclrw(base, sizeof(ClassList)); - base->base = baseclass; - base->access = access; - base->is_virtual = is_virtual; - if ((scan = tclass->bases)) { - while (scan->next) - scan = scan->next; - scan->next = base; - } else { - tclass->bases = base; - } - } - } while ((tk = lex()) == ','); - - if (tclass->flags & CLASS_HAS_VBASES) - CDecl_MakeVBaseList(tclass); - - if (copts.def_inherited && tclass->bases && !tclass->bases->next) { - inherited_type = galloc(sizeof(ObjType)); - memclrw(inherited_type, sizeof(ObjType)); - inherited_type->otype = OT_TYPE; - inherited_type->access = ACCESSPUBLIC; - inherited_type->type = TYPE(tclass->bases->base); - CScope_AddObject(tclass->nspace, GetHashNameNodeExport("inherited"), OBJ_BASE(inherited_type)); - } -} - -static AccessType getaccesstype(AccessType a, AccessType b, AccessType c) { - if (a == ACCESSNONE || b == ACCESSNONE || b == ACCESSPRIVATE) - return ACCESSNONE; - - if (c == ACCESSPUBLIC && b != ACCESSPUBLIC) - return ACCESSNONE; - - return ACCESSPUBLIC; -} - -static TypeMemberFunc *CDecl_MakeDefaultCtorType(TypeClass *tclass) { - TypeMemberFunc *tmeth = galloc(sizeof(TypeMemberFunc)); - memclrw(tmeth, sizeof(TypeMemberFunc)); - tmeth->type = TYPEFUNC; - tmeth->functype = TYPE(&void_ptr); - tmeth->flags = FUNC_IS_CTOR | FUNC_AUTO_GENERATED | FUNC_METHOD; - tmeth->theclass = tclass; - CDecl_SetFuncFlags(TYPE_FUNC(tmeth), 1); - - if (tclass->flags & CLASS_HAS_VBASES) - CDecl_AddArgument(TYPE_FUNC(tmeth), TYPE(&stsignedshort)); - - CDecl_AddThisPointerArgument(TYPE_FUNC(tmeth), tclass); - return tmeth; -} - -static void CDecl_AddDefArgConstructor(TypeClass *tclass) { - // empty -} - -static void CDecl_AddMemberFunctionObject(TypeClass *tclass, HashNameNode *name, TypeMemberFunc *tmeth, AccessType access) { - Object *obj = CParser_NewCompilerDefFunctionObject(); - obj->name = name; - obj->type = TYPE(tmeth); - obj->qual = Q_MANGLE_NAME; - obj->access = access; - obj->nspace = tclass->nspace; - obj->qual = obj->qual | Q_INLINE; - CScope_AddObject(tclass->nspace, obj->name, OBJ_BASE(obj)); -} - -static void CDecl_AddDefaultConstructor(ClassLayout *decle, TypeClass *tclass) { - ClassList *base; - ObjMemberVar *ivar; - Object *obj; - Boolean has_ctor; - - if (CClass_Constructor(tclass)) { - CDecl_AddDefArgConstructor(tclass); - return; - } - - has_ctor = 0; - - if (tclass->flags & CLASS_HAS_VBASES) - has_ctor = 1; - if (decle->has_vtable) - has_ctor = 1; - - for (base = tclass->bases; base; base = base->next) { - if (CClass_Constructor(base->base)) - has_ctor = 1; - } - - for (ivar = tclass->ivars; ivar; ivar = ivar->next) { - Type *type = ivar->type; - while (IS_TYPE_ARRAY(type)) - type = TYPE_POINTER(type)->target; - if (IS_TYPE_CLASS(type) && CClass_Constructor(TYPE_CLASS(type))) - has_ctor = 1; - } - - if (has_ctor) { - CDecl_AddMemberFunctionObject( - tclass, - constructor_name_node, - CDecl_MakeDefaultCtorType(tclass), - ACCESSPUBLIC - ); - } -} - -static TypeMemberFunc *CDecl_MakeCopyCtorType(TypeClass *tclass, Boolean is_const) { - FuncArg *arg; - TypeMemberFunc *tmeth = galloc(sizeof(TypeMemberFunc)); - memclrw(tmeth, sizeof(TypeMemberFunc)); - tmeth->type = TYPEFUNC; - tmeth->functype = TYPE(&void_ptr); - tmeth->flags = FUNC_IS_CTOR | FUNC_AUTO_GENERATED | FUNC_METHOD; - tmeth->theclass = tclass; - CDecl_SetFuncFlags(TYPE_FUNC(tmeth), 1); - - arg = CParser_NewFuncArg(); - if (is_const) - arg->qual = Q_CONST; - arg->type = CDecl_NewRefPointerType(TYPE(tclass)); - tmeth->args = arg; - - if (tclass->flags & CLASS_HAS_VBASES) - CDecl_AddArgument(TYPE_FUNC(tmeth), TYPE(&stsignedshort)); - - CDecl_AddThisPointerArgument(TYPE_FUNC(tmeth), tclass); - return tmeth; -} - -static void CDecl_AddDefaultCopyConstructor(ClassLayout *decle, TypeClass *tclass) { - ClassList *base; - ObjMemberVar *ivar; - Object *obj; - AccessType access; - Boolean has_copyctor; - Boolean is_const; - FuncArg *arg; - - if (CClass_CopyConstructor(tclass)) - return; - - access = ACCESSPUBLIC; - is_const = 1; - has_copyctor = 0; - - if (CClass_Constructor(tclass)) - has_copyctor = 1; - if ((tclass->flags & CLASS_HAS_VBASES) || decle->has_vtable) - has_copyctor = 1; - - for (base = tclass->bases; base; base = base->next) { - if ((obj = CClass_CopyConstructor(base->base))) { - has_copyctor = 1; - access = getaccesstype(access, obj->access, ACCESSPRIVATE); - arg = TYPE_FUNC(obj->type)->args->next; - if (base->base->flags & CLASS_HAS_VBASES) - arg = arg->next; - if (!(arg->qual & Q_CONST)) - is_const = 0; - } - } - - for (ivar = tclass->ivars; ivar; ivar = ivar->next) { - Type *type = ivar->type; - while (IS_TYPE_ARRAY(type)) - type = TYPE_POINTER(type)->target; - if (IS_TYPE_CLASS(type) && (obj = CClass_CopyConstructor(TYPE_CLASS(type)))) { - has_copyctor = 1; - access = getaccesstype(access, obj->access, ACCESSPUBLIC); - arg = TYPE_FUNC(obj->type)->args->next; - if (TYPE_CLASS(type)->flags & CLASS_HAS_VBASES) - arg = arg->next; - if (!(arg->qual & Q_CONST)) - is_const = 0; - } - } - - if (has_copyctor) { - CDecl_AddMemberFunctionObject( - tclass, - constructor_name_node, - CDecl_MakeCopyCtorType(tclass, is_const), - access - ); - } -} - -static TypeMemberFunc *CDecl_MakeAssignmentOperatorType(TypeClass *tclass, Boolean is_const) { - FuncArg *arg; - TypeMemberFunc *tmeth = galloc(sizeof(TypeMemberFunc)); - memclrw(tmeth, sizeof(TypeMemberFunc)); - tmeth->type = TYPEFUNC; - tmeth->functype = CDecl_NewRefPointerType(TYPE(tclass)); - tmeth->flags = FUNC_AUTO_GENERATED | FUNC_METHOD; - tmeth->theclass = tclass; - CDecl_SetFuncFlags(TYPE_FUNC(tmeth), 1); - - arg = CParser_NewFuncArg(); - if (is_const) - arg->qual = Q_CONST; - arg->type = CDecl_NewRefPointerType(TYPE(tclass)); - tmeth->args = arg; - - CDecl_AddThisPointerArgument(TYPE_FUNC(tmeth), tclass); - return tmeth; -} - -static void CDecl_AddDefaultAssignmentOperator(ClassLayout *decle, TypeClass *tclass) { - ClassList *base; - ObjMemberVar *ivar; - Object *obj; - AccessType access; - Boolean is_const; - Boolean has_ass; - DeclInfo declinfo; - - is_const = 1; - has_ass = 0; - access = ACCESSPUBLIC; - - if (!CClass_AssignmentOperator(tclass)) { - if (!copts.old_argmatch) - has_ass = 1; - - if ((tclass->flags & CLASS_HAS_VBASES) || decle->has_vtable || CClass_MemberObject(tclass, asop_name_node)) - has_ass = 1; - - for (base = tclass->bases; base; base = base->next) { - if ((obj = CClass_AssignmentOperator(base->base))) { - has_ass = 1; - access = getaccesstype(access, obj->access, ACCESSPRIVATE); - if (!(TYPE_FUNC(obj->type)->args->next->qual & Q_CONST)) - is_const = 0; - } - } - - for (ivar = tclass->ivars; ivar; ivar = ivar->next) { - Type *type = ivar->type; - while (IS_TYPE_ARRAY(type)) - type = TYPE_POINTER(type)->target; - if (IS_TYPE_CLASS(type) && (obj = CClass_AssignmentOperator(TYPE_CLASS(type)))) { - has_ass = 1; - access = getaccesstype(access, obj->access, ACCESSPUBLIC); - if (!(TYPE_FUNC(obj->type)->args->next->qual & Q_CONST)) - is_const = 0; - } - } - } - - if (has_ass) { - memclrw(&declinfo, sizeof(DeclInfo)); - declinfo.qual |= Q_INLINE; - declinfo.thetype = (Type *) CDecl_MakeAssignmentOperatorType(tclass, is_const); - declinfo.name = asop_name_node; - CDecl_AddFunctionMember(decle, tclass, &declinfo, access, 1, 0, 0, 0); - } -} - -TypeMemberFunc *CDecl_MakeDefaultDtorType(TypeClass *tclass, Boolean is_virtual) { - TypeMemberFunc *tmeth = galloc(sizeof(TypeMemberFunc)); - memclrw(tmeth, sizeof(TypeMemberFunc)); - tmeth->type = TYPEFUNC; - tmeth->functype = (Type *) &void_ptr; - tmeth->flags = FUNC_IS_DTOR | FUNC_AUTO_GENERATED | FUNC_METHOD; - tmeth->theclass = tclass; - CDecl_SetFuncFlags(TYPE_FUNC(tmeth), 1); - if (is_virtual) - CDecl_AddArgument(TYPE_FUNC(tmeth), TYPE(&stsignedshort)); - CDecl_AddThisPointerArgument(TYPE_FUNC(tmeth), tclass); - return tmeth; -} - -static void CDecl_AddDefaultDestructor(ClassLayout *decle, TypeClass *tclass) { - ClassList *base; - ObjMemberVar *ivar; - Object *obj; - AccessType access; - Boolean has_dtor; - Boolean is_virtual; - DeclInfo declinfo; - - if (CClass_Destructor(tclass)) - return; - - has_dtor = 0; - is_virtual = 0; - access = ACCESSPUBLIC; - - for (base = tclass->bases; base; base = base->next) { - if ((obj = CClass_Destructor(base->base))) { - has_dtor = 1; - if (obj->datatype == DVFUNC) - is_virtual = 1; - access = getaccesstype(access, obj->access, ACCESSPRIVATE); - } - } - - for (ivar = tclass->ivars; ivar; ivar = ivar->next) { - Type *type = ivar->type; - while (IS_TYPE_ARRAY(type)) - type = TYPE_POINTER(type)->target; - if (IS_TYPE_CLASS(type) && (obj = CClass_Destructor(TYPE_CLASS(type)))) { - has_dtor = 1; - access = getaccesstype(access, obj->access, ACCESSPUBLIC); - } - } - - if (has_dtor) { - memclrw(&declinfo, sizeof(DeclInfo)); - declinfo.qual |= Q_INLINE; - if (is_virtual) - declinfo.qual |= Q_VIRTUAL; - - declinfo.thetype = (Type *) CDecl_MakeDefaultDtorType(tclass, 1); - declinfo.name = destructor_name_node; - CDecl_AddFunctionMember(decle, tclass, &declinfo, access, 1, 0, 0, 0); - } -} - -static void CDecl_SetupClassLayout(ClassLayout *decle, TypeClass *tclass, ObjBase **objbuf) { - SInt32 index; - SInt32 i; - Object *obj; - CScopeObjectIterator iter; - ObjMemberVar *ivar; - SInt32 bufsize; - - if (decle->lex_order_count > 32) { - bufsize = decle->lex_order_count * sizeof(ObjBase *); - objbuf = lalloc(bufsize); - } else { - bufsize = 32 * sizeof(ObjBase *); - } - memclrw(objbuf, bufsize); - decle->objlist = objbuf; - - CScope_InitObjectIterator(&iter, tclass->nspace); - index = 0; - while (1) { - obj = OBJECT(CScope_NextObjectIteratorObject(&iter)); - if (!obj) break; - - if (!IS_TYPE_FUNC(obj->type)) - continue; - if (!IS_TYPEFUNC_METHOD(TYPE_FUNC(obj->type))) - continue; - if (obj->datatype == DALIAS) - continue; - - i = TYPE_METHOD(obj->type)->vtbl_index; - if (i > 0) { - CError_ASSERT(6363, (i - 1) < decle->lex_order_count && !objbuf[(int) (i - 1)]); - objbuf[(int) (i - 1)] = OBJ_BASE(obj); - index++; - if (obj->datatype != DVFUNC && !TYPE_METHOD(obj->type)->is_static && CClass_OverridesBaseMember(tclass, obj->name, obj)) - CDecl_MakeFunctionVirtual(tclass, obj); - - if (obj->datatype == DVFUNC) { - decle->has_vtable = 1; - if (!tclass->vtable) { - CABI_AddVTable(tclass); - decle->xA = i - 1; - } else { - if ((i - 1) < decle->xA) - decle->xA = i - 1; - } - } else if (TYPE_FUNC(obj->type)->flags & FUNC_PURE) { - CError_Error(CErrorStr351, obj); - TYPE_FUNC(obj->type)->flags &= ~FUNC_PURE; - } - } else { - CError_ASSERT(6412, i == 0); - } - - if (!tclass->sominfo) - TYPE_METHOD(obj->type)->vtbl_index = 0; - } - - if (!tclass->action) { - for (i = 0; i < decle->lex_order_count; i++) { - Object *obj2 = OBJECT(objbuf[i]); - if (obj2 && obj2->datatype == DVFUNC && !(obj2->qual & Q_INLINE) && !(TYPE_FUNC(obj2->type)->flags & FUNC_PURE)) { - tclass->action = CLASS_ACTION_1; - TYPE_FUNC(obj2->type)->flags |= FUNC_FLAGS_4; - break; - } - } - } - - if (!tclass->sominfo) { - for (i = 0, ivar = tclass->ivars; i < decle->lex_order_count; i++) { - if (!objbuf[i]) { - CError_ASSERT(6449, ivar); - objbuf[i] = OBJ_BASE(ivar); - ivar = ivar->next; - index++; - } - } - CError_ASSERT(6455, ivar == NULL); - } - - CError_ASSERT(6458, index == decle->lex_order_count); -} - -void CDecl_CompleteClass(ClassLayout *decle, TypeClass *tclass) { - ClassList *base; - ObjBase *buf[32]; - - for (base = tclass->bases; base; base = base->next) { - if (base->base->vtable) - decle->has_vtable = 1; - } - - if (!tclass->sominfo) { - CDecl_AddDefaultDestructor(decle, tclass); - CDecl_AddDefaultAssignmentOperator(decle, tclass); - CDecl_AddDefaultConstructor(decle, tclass); - CDecl_AddDefaultCopyConstructor(decle, tclass); - } - - CDecl_SetupClassLayout(decle, tclass, buf); - if (decle->has_vtable) - CClass_CheckOverrides(tclass); - CABI_LayoutClass(decle, tclass); - if (tclass->sominfo) - CSOM_ClassComplete(tclass); - - if ((tclass->flags & CLASS_IS_TEMPL_INST) && !TEMPL_CLASS_INST(tclass)->is_specialized) - tclass->action = CLASS_ACTION_0; - - if (!tclass->action) - CClass_MakeStaticActionClass(tclass); - CClass_ClassDefaultFuncAction(tclass); -} - -TypeClass *CDecl_DefineClass(NameSpace *nspace, HashNameNode *name, TypeClass *tclass, short mode, Boolean flag2, Boolean flag3) { - NameSpace *mynspace; - ObjType *objtype; - - if (!tclass && nspace->theclass && (nspace->theclass->flags & CLASS_IS_TEMPL)) { - CError_ASSERT(6556, !flag2); - return TYPE_CLASS(CTemplClass_DefineNestedClass(TEMPL_CLASS(nspace->theclass), name, mode)); - } - - mynspace = CScope_NewListNameSpace(name, 1); - if (!tclass) { - tclass = galloc(sizeof(TypeClass)); - memclrw(tclass, sizeof(TypeClass)); - } - - tclass->type = TYPECLASS; - tclass->align = 1; - tclass->mode = mode; - tclass->action = CLASS_ACTION_0; - if (name) { - tclass->classname = name; - if (flag3) { - if (flag2) { - objtype = galloc(sizeof(ObjType)); - memclrw(objtype, sizeof(ObjType)); - objtype->otype = OT_TYPE; - objtype->access = ACCESSPUBLIC; - objtype->type = (Type *) tclass; - CScope_AddObject(nspace, name, OBJ_BASE(objtype)); - } else { - CScope_DefineTypeTag(nspace, name, (Type *) tclass); - } - } - CScope_DefineTypeTag(mynspace, name, (Type *) tclass); - - if (cscope_currentfunc) - mynspace->name = CParser_AppendUniqueNameFile(name->name); - - if (copts.direct_to_som && nspace == cscope_root && !strcmp(name->name, "SOMObject")) - CSOM_MakeSOMClass(tclass); - } else { - tclass->classname = CParser_AppendUniqueNameFile("@class"); - mynspace->name = tclass->classname; - } - - tclass->nspace = mynspace; - mynspace->theclass = tclass; - mynspace->parent = nspace; - if (!nspace->is_global) - CParser_RegisterNonGlobalClass(tclass); - - return tclass; -} - -void CDecl_ParseClassDeclSpec(UInt8 *declspec) { - DeclInfo declinfo; - - if ((tk = lex()) == '(') { - memclrw(&declinfo, sizeof(DeclInfo)); - CParser_ParseDeclSpec(&declinfo, 1); - if (declinfo.exportflags & EXPORT_FLAGS_INTERNAL) - *declspec = *declspec | CLASS_EFLAGS_INTERNAL; - if (declinfo.exportflags & EXPORT_FLAGS_IMPORT) - *declspec = *declspec | CLASS_EFLAGS_IMPORT; - if (declinfo.exportflags & EXPORT_FLAGS_EXPORT) - *declspec = *declspec | CLASS_EFLAGS_EXPORT; - if ((tk = lex()) != ')') - CError_Error(CErrorStr115); - else - tk = lex(); - } else { - CError_Error(CErrorStr114); - } -} - -static TemplClass *CDecl_SpecializeTemplateClass(TemplClass *tmclass) { - tmclass->theclass.nspace->names = 0; - tmclass->theclass.nspace->data.list = NULL; - tmclass->theclass.ivars = NULL; - tmclass->theclass.bases = NULL; - tmclass->theclass.vbases = NULL; - tmclass->theclass.friends = NULL; - tmclass->theclass.vtable = NULL; - tmclass->members = NULL; - tmclass->instances = NULL; - tmclass->pspec_owner = NULL; - tmclass->pspecs = NULL; - tmclass->actions = NULL; - tmclass->lex_order_count = 0; - tmclass->align = 0; - tmclass->flags = TEMPLCLASS_FLAGS_2; - return tmclass; -} - -void CDecl_ParseClass(DeclInfo *declinfo, short mode, Boolean flag1, UInt8 class_declspec) { - ClassLayout decle; - TypeClass *tclass; - HashNameNode *classname; - Type *search; - short t; - NameSpace *nspace; - NameResult pr; - CScopeSave scopesave; - GList gl; - FileOffsetInfo offsetsave; - SInt32 offset; - Boolean is_templ; - Boolean add_to_browse; - - memclrw(&decle, sizeof(ClassLayout)); - if (declinfo->x28) { - tclass = TYPE_CLASS(declinfo->x28); - } else { - if (tk == TK_UU_DECLSPEC) - CDecl_ParseClassDeclSpec(&class_declspec); - - switch (tk) { - case ':': - case '{': - tclass = CDecl_DefineClass(cscope_current, NULL, NULL, mode, 0, 1); - tclass->eflags |= class_declspec; - break; - case TK_IDENTIFIER: - classname = tkidentifier; - if (!declinfo->in_friend_decl && !declinfo->x4F && ((t = lookahead()) == ':' || t == ';' || t == '{')) { - tk = lex(); - search = CScope_GetLocalTagType(cscope_current, classname); - if (search) { - tagtype_search: - if (!IS_TYPE_CLASS(search)) { - if ((IS_TYPE_TEMPLATE(search) || IS_TYPE_STRUCT(search)) && tk != '{' && tk != ':') { - declinfo->thetype = search; - return; - } - if (!IS_TYPE_TEMPLATE(search) || !(tclass = TYPE_CLASS(CTemplTool_GetSelfRefTemplate(search)))) { - CError_Error(CErrorStr132, classname->name); - tclass = CDecl_DefineClass(cscope_current, NULL, NULL, mode, 0, 1); - break; - } - } else { - tclass = TYPE_CLASS(search); - } - if (tclass->mode != mode) { - if ( - (mode == CLASS_MODE_CLASS && tclass->mode == CLASS_MODE_STRUCT) || - (mode == CLASS_MODE_STRUCT && tclass->mode == CLASS_MODE_CLASS) - ) - { - if (copts.warn_structclass) - CError_Warning(CErrorStr343); - } else { - CError_Error(CErrorStr132, classname); - } - } - tclass->eflags |= class_declspec; - break; - } else { - tclass = CDecl_DefineClass(cscope_current, classname, NULL, mode, 0, 1); - tclass->eflags |= class_declspec; - break; - } - } else { - tkidentifier = classname; - } - default: - if (!CScope_ParseElaborateName(&pr)) { - CError_Error(CErrorStr121); - declinfo->thetype = TYPE(&stsignedint); - return; - } - - tk = lex(); - if ((search = pr.type)) { - goto tagtype_search; - } - - CError_ASSERT(6786, pr.name_4); - - tclass = CDecl_DefineClass(CScope_FindNonClassNonFunctionNS(cscope_current), pr.name_4, NULL, mode, 0, 1); - tclass->eflags |= class_declspec; - } - } - - declinfo->thetype = TYPE(tclass); - if (tk == ':' || tk == '{') { - if (declinfo->in_friend_decl) - CError_Error(CErrorStr201); - - if (tclass->flags & CLASS_COMPLETED) { - if ( - (tclass->flags & CLASS_IS_TEMPL) && - !TEMPL_CLASS(tclass)->instances && - !(TEMPL_CLASS(tclass)->flags & TEMPLCLASS_FLAGS_2) - ) - { - tclass = TYPE_CLASS(CDecl_SpecializeTemplateClass(TEMPL_CLASS(tclass))); - } else { - CError_Error(CErrorStr132, tclass->classname->name); - tclass = CDecl_DefineClass(cscope_current, NULL, NULL, mode, 0, 1); - } - } - - for (nspace = cscope_current; nspace; nspace = nspace->parent) { - if (nspace == tclass->nspace) { - CError_Error(CErrorStr132, tclass->classname->name); - tclass = CDecl_DefineClass(cscope_current, NULL, NULL, mode, 0, 1); - break; - } - } - - is_templ = (tclass->flags & CLASS_IS_TEMPL) != 0; - if (tclass->flags & CLASS_IS_TEMPL_INST) { - TEMPL_CLASS_INST(tclass)->is_instantiated = 1; - if (!declinfo->x28) - TEMPL_CLASS_INST(tclass)->is_specialized = 1; - } - - CError_ASSERT(6853, copts.structalignment >= 0 && copts.structalignment <= 14); - - tclass->eflags = tclass->eflags | (((copts.structalignment + 1) << 4) & 0xF0); - if (tk == ':') - CDecl_ParseBaseClassList(tclass, mode, is_templ); - - CScope_SetClassDefScope(tclass, &scopesave); - if (tk == '{') { - tk = lex(); - if ((add_to_browse = cparamblkptr->browseoptions.recordClasses && declinfo->file->recordbrowseinfo)) { - offsetsave = member_fileoffset; - CBrowse_BeginClass(declinfo, &gl); - } - CDecl_ParseClassMembers(&decle, tclass, mode); - offset = CPrep_BrowserFileOffset(); - if (flag1) - tk = lex(); - if (add_to_browse) { - member_fileoffset = offsetsave; - if (flag1 && tk == ';') - CPrep_BrowserFileOffset(); - CBrowse_EndClass(offset, &gl); - } - } else { - CError_Error(CErrorStr135); - } - - if (is_templ) - CTemplClass_CompleteClass(TEMPL_CLASS(tclass), &decle); - else - CDecl_CompleteClass(&decle, tclass); - CScope_RestoreScope(&scopesave); - } -} |