summaryrefslogtreecommitdiff
path: root/compiler_and_linker/unsorted/CDecl.c
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
committerAsh Wolf <ninji@wuffs.org>2023-01-26 11:30:47 +0000
commit094b96ca1df4a035b5f93c351f773306c0241f3f (patch)
tree95ce05e3ebe816c7ee7996206bb37ea17d8ca33c /compiler_and_linker/unsorted/CDecl.c
parentfc0c4c0df7b583b55a08317cf1ef6a71d27c0440 (diff)
downloadMWCC-main.tar.gz
MWCC-main.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.c4845
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);
- }
-}