diff options
author | Ash Wolf <ninji@wuffs.org> | 2022-11-07 03:06:21 +0000 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2022-11-07 03:06:21 +0000 |
commit | 9a46dd0e2e80790d9848c0bbd718932a27c23269 (patch) | |
tree | e7a8e976c7138d50a69ff4778c4e8572efd94452 /compiler_and_linker/FrontEnd | |
parent | d0b9848c54e6f85ab713f059dcd1ddef7e57caa6 (diff) | |
download | MWCC-9a46dd0e2e80790d9848c0bbd718932a27c23269.tar.gz MWCC-9a46dd0e2e80790d9848c0bbd718932a27c23269.zip |
honk
Diffstat (limited to 'compiler_and_linker/FrontEnd')
-rw-r--r-- | compiler_and_linker/FrontEnd/C/CPrep.c | 2984 | ||||
-rw-r--r-- | compiler_and_linker/FrontEnd/C/CPrepTokenizer.c | 1941 | ||||
-rw-r--r-- | compiler_and_linker/FrontEnd/C/CScope.c | 22 |
3 files changed, 4754 insertions, 193 deletions
diff --git a/compiler_and_linker/FrontEnd/C/CPrep.c b/compiler_and_linker/FrontEnd/C/CPrep.c index e69bcfb..4e3ffea 100644 --- a/compiler_and_linker/FrontEnd/C/CPrep.c +++ b/compiler_and_linker/FrontEnd/C/CPrep.c @@ -1,7 +1,47 @@ #include "compiler.h" #include "compiler/CError.h" +#include "compiler/CInt64.h" +#include "compiler/objects.h" +#include "compiler/scopes.h" #include "compiler/tokens.h" #include "cos.h" +#include "compiler/CMachine.h" +#include "compiler/CParser.h" +#include "compiler/CPrep.h" +#include "compiler/CPrepTokenizer.h" +#include "compiler/CScope.h" +#include "compiler/CodeGen.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +typedef struct PrepValue { + CInt64 val; + char is_unsigned; +} PrepValue; + +typedef struct IfStack { + CPrepFileInfo *file; + SInt32 pos; + short state; +} IfStack; + +enum { + IfState_0 = 0, + IfState_1 = 1, + IfState_2 = 2, + IfState_3 = 3, + IfState_4 = 4, + IfState_5 = 5 +}; + +// forward declarations +static PrepValue CPrep_ParseCond(); +static PrepValue CPrep_ParseBinary(PrepValue *rhs, short op); +static char *XpandMacro(Macro *macro); +static void prepmacro(Macro *macro); +static void prepifskip(); +static void gotonexttoken(); extern SInt16 *CLT_filesp; extern CPrepFileInfo **CLT_filestack; @@ -9,11 +49,13 @@ extern CPrepFileInfo **CLT_filestack; //#define OPT_OFFSET(optname) ((short) (((char *) (&copts.optname)) - ((char *) &copts))) #define OPT_OFFSET(optname) ((short) ( &((COpts *)0)->optname )) enum { + OPT_OFFSET_MASK = 0x1FFF, OPT_FLAG_2000 = 0x2000, - OPT_FLAG_4000 = 0x4000 + OPT_FLAG_4000 = 0x4000, + OPT_FLAG_8000 = 0x8000 }; -struct { +struct CompilerOption { char *name; short bits; } compileroptions[138] = { @@ -172,15 +214,15 @@ Macro **macrohashtable; Boolean cprep_nomem_exit; Boolean cprep_nostring; Boolean cprep_eoltokens; -static void *ifstack[100]; // TODO type+size +static IfStack ifstack[64]; static short iflevel; TokenStack tokenstack[128]; short tokenstacklevel; -SInt32 cprep_cursymfile; // might be a ptr? +CPrepFileInfo *cprep_cursymfile; char *pos; char *macropos; char *nextcharpos; -char CPrep_SkipNewCommentChar; +unsigned char CPrep_SkipNewCommentChar; Boolean preprocessing_only; Handle stringmem; SInt32 maxstringsize; @@ -197,8 +239,12 @@ CPrepFileInfo *prep_file; short filesp; SInt32 linenumber; static CPrepFileInfo *filestack[32]; -static void *cprep_files; // TODO type -static SInt32 linetick; +typedef struct CPrepFileInfoList { + struct CPrepFileInfoList *next; + CPrepFileInfo *fileinfo; +} CPrepFileInfoList; +static CPrepFileInfoList *cprep_files; +static UInt32 linetick; static Boolean waslockedmacro; static Boolean include_once; static time_t now_time; @@ -206,7 +252,11 @@ static SInt32 lineoffset; static Boolean was_prep_error; static Boolean cprep_hasprepline; static Boolean cprep_incondexpr; -static void *cprep_packstack[100]; // TODO type+size +struct PackStack { + HashNameNode *identifier; + short align_mode; +}; +static struct PackStack cprep_packstack[128]; static short cprep_packstackp; static Macro lineM; static Macro fileM; @@ -227,9 +277,15 @@ struct COptsPush { struct COptsPush *next; COpts opts; }; +struct COptPush { + struct COptPush *next; + SInt32 id; + Boolean x8; + UInt8 value; +}; static struct COptsPush *coptpushs; -static void *coptpush; // TODO type -static void *coptssave; // TODO type +static struct COptPush *coptpush; +static COpts *coptssave; static Boolean dofreeaheap; static GList mlist; static Handle ts_buffer; @@ -240,8 +296,10 @@ static SInt32 ts_elements; SInt32 ts_preread_elements; static SInt32 gDirectiveStart; static SInt32 high_mem_mark; -// static TStreamElement dummyelement; // in CPrep_CurStreamElement static short exprtk; +#ifdef __MWERKS__ +#pragma options align=reset +#endif static void cannotopenerror(StringPtr filename, Boolean err) { static char fname[64]; @@ -433,11 +491,15 @@ static Boolean setupfile(StringPtr filename, Boolean flag1, Boolean flag2) { OSType file_type; SInt32 file_size; SInt32 file_dirid; - CWMemHandle cache_hnd; void *cache; + CWMemHandle cache_hnd; SInt16 refnum; SInt16 file_vrefnum; char *extpos; + unsigned char *src; + char *append; + char *dst; + int len; if (filesp >= 31) { was_prep_error = 1; @@ -446,10 +508,10 @@ static Boolean setupfile(StringPtr filename, Boolean flag1, Boolean flag2) { } memclrw(&prepinfo, sizeof(CPrepFileInfo)); - prepinfo.unkfield126 = !flag1; // may be wrong field! + prepinfo.unkfield126 = !flag1; if (filename) { memclrw(&fileinfo, sizeof(CWFileInfo)); - fileinfo.fullsearch = flag2; + fileinfo.fullsearch = flag1; fileinfo.dependencyType = cwNormalDependency; fileinfo.isdependentoffile = -1; memcpy(myfilename, &filename[1], filename[0]); @@ -458,7 +520,26 @@ static Boolean setupfile(StringPtr filename, Boolean flag1, Boolean flag2) { if (CWFindAndLoadFile(cparamblkptr->context, myfilename, &fileinfo) != cwNoErr) { if (filename[0] + strlen(".framework/Headers") < 255) { if ((extpos = strchr(myfilename, '/'))) { - // Do Me! 37D8C + src = filename + 1; + append = ".framework/Headers"; + dst = myfilename; + len = filename[0]; + while (dst < extpos) { + *(dst++) = *(src++); + len--; + } + while (*append) { + *(dst++) = *(append++); + } + while (len) { + *(dst++) = *(src++); + len--; + } + *dst = 0; + if (CWFindAndLoadFile(cparamblkptr->context, myfilename, &fileinfo) != cwNoErr) { + cannotopenerror(filename, 0); + return 0; + } } else { cannotopenerror(filename, 0); return 0; @@ -598,19 +679,519 @@ void CPrep_TokenStreamSetCurState(SInt32 *state) { tk = lex(); } -static void CPrep_StreamSkipToBrace() {} -static void CPrep_StreamSkipBlock() {} -void CPrep_StreamGetBlock() {} -void CPrep_StreamGetSemicolon() {} -void CPrep_StreamGetTemplate() {} -void CPrep_StreamInsert() {} -void CPrep_StreamRemove() {} -void CPrep_RemoveTokens() {} -void CPrep_TokenStreamFlush() {} -static void CPrep_TokenSize() {} -void CPrep_CurStreamElement() {} +static SInt32 CPrep_StreamSkipToBrace(CPrepStreamFuncPtr func, SInt32 val) { + TStreamElement ts; + SInt32 v = val + 1; + + do { + switch (lex()) { + case '{': + return v; + case 0: + case ';': + return 0; + case TK_IDENTIFIER: + if (func) { + ts = ts_current[-1]; + func(&ts); + ts_current[-1] = ts; + tk = ts.tokentype; + } + break; + } + v++; + } while (1); +} + +static SInt32 CPrep_StreamSkipBlock(CPrepStreamFuncPtr func, SInt32 val) { + TStreamElement ts; + SInt32 brace_level; + char save_asmpoundcomment; + char save_cplusplus; + char starttoken; + char endtoken; + SInt32 level; + SInt32 v; + SInt16 t; + + save_asmpoundcomment = copts.asmpoundcomment; + save_cplusplus = copts.cplusplus; + level = 0; + brace_level = 1; + v = val + 1; + +loop: + v++; + switch ((t = lex())) { + case 0: + return 0; + case TK_ASM: + cprep_nostring = 1; + v++; + t = lex(); + if ((t == TK_VOLATILE) || ((t == TK_IDENTIFIER) && !strcmp(tkidentifier->name, "__volatile__"))) { + v++; + t = lex(); + } + if (!t) + return 0; + if (t == TK_NEG7) { + t = lex(); + v++; + } + if (t == '(') { + starttoken = '('; + endtoken = ')'; + } else if (t == '{') { + starttoken = '{'; + endtoken = '}'; + brace_level++; + } + level = 1; + in_assembler = 1; + v++; + t = lex(); + if (t == '"') { + copts.cplusplus = 0; + copts.asmpoundcomment = 1; + goto loop; + } + if (t) + goto loop; + return 0; + + case '(': + if (starttoken == t) + level++; + goto loop; + case ')': + if (level && endtoken == t && !--level) { + cprep_nostring = 0; + in_assembler = 0; + copts.cplusplus = save_cplusplus; + copts.asmpoundcomment = save_asmpoundcomment; + } + goto loop; + + case TK_IDENTIFIER: + if (func) { + ts = ts_current[-1]; + func(&ts); + ts_current[-1] = ts; + tk = ts.tokentype; + } + goto loop; + + case '{': + brace_level++; + if (starttoken == t) + level++; + goto loop; + case '}': + if (level && endtoken == t && !--level) { + cprep_nostring = 0; + in_assembler = 0; + copts.cplusplus = save_cplusplus; + copts.asmpoundcomment = save_asmpoundcomment; + } + if (--brace_level > 0) + goto loop; + break; + default: + goto loop; + } + + return v; +} + +void CPrep_StreamGetBlock(TStream *stream, CPrepStreamFuncPtr func, int arg) { + Boolean save_eoltokens; + SInt32 start_offset; + Boolean tryflag; + SInt32 count; + + start_offset = ts_current - ts_first - 1; + tryflag = 0; + stream->tokens = 0; + stream->firsttoken = NULL; + count = 0; + save_eoltokens = cprep_eoltokens; + cprep_eoltokens = 1; + + switch (tk) { + case TK_TRY: + tryflag = 1; + case ':': + if (!(count = CPrep_StreamSkipToBrace(func, 0))) { + CError_Error(121); + cprep_eoltokens = save_eoltokens; + return; + } + case '{': + break; + default: + CError_Error(121); + cprep_eoltokens = save_eoltokens; + return; + } + + if (!(count = CPrep_StreamSkipBlock(func, count))) { + CError_Error(121); + cprep_eoltokens = save_eoltokens; + return; + } + + if (tryflag) { + tryloop: + switch (lex()) { + case TK_NEG7: + count++; + goto tryloop; + case TK_CATCH: + if (!(count = CPrep_StreamSkipToBrace(func, count)) || !(count = CPrep_StreamSkipBlock(func, count))) { + CError_Error(242); + cprep_eoltokens = save_eoltokens; + return; + } + if (lookahead_noeol() == TK_CATCH) + goto tryloop; + break; + default: + CError_Error(242); + cprep_eoltokens = save_eoltokens; + return; + } + } + + cprep_eoltokens = save_eoltokens; + stream->tokens = count; + stream->firsttoken = galloc(count * sizeof(TStreamElement)); + memcpy(stream->firsttoken, ts_first + start_offset, count * sizeof(TStreamElement)); +} + +void CPrep_StreamGetSemicolon(TStream *stream, CPrepStreamFuncPtr func) { + SInt32 count; + SInt32 start_offset; + Boolean save_eoltokens; + + start_offset = ts_current - ts_first - 1; + save_eoltokens = cprep_eoltokens; + cprep_eoltokens = 1; + stream->tokens = 0; + stream->firsttoken = NULL; + count = 1; + + while (tk && tk != ';') { + tk = lex(); + if ((tk == TK_IDENTIFIER) && func) { + func(&ts_current[-1]); + tk = ts_current[-1].tokentype; + } + count++; + } + + stream->tokens = count; + stream->firsttoken = galloc(count * sizeof(TStreamElement)); + memcpy(stream->firsttoken, ts_first + start_offset, count * sizeof(TStreamElement)); + cprep_eoltokens = save_eoltokens; +} + +void CPrep_StreamGetTemplate(TStream *stream, CPrepStreamFuncPtr func) { + SInt32 count; + SInt32 start_offset; + Boolean save_eoltokens; + SInt16 level; + + start_offset = ts_current - ts_first - 1; + save_eoltokens = cprep_eoltokens; + cprep_eoltokens = 1; + stream->tokens = 0; + stream->firsttoken = NULL; + count = 0; + +loop: + switch (tk) { + case 0: + CError_ErrorTerm(102); + case '}': + CError_Error(229); + return; + case ';': + count++; + break; + case TK_IDENTIFIER: + if (func) { + func(&ts_current[-1]); + tk = ts_current[-1].tokentype; + } + default: + count++; + tk = lex(); + goto loop; + case '{': + level = 0; + do { + count++; + switch (tk) { + case TK_IDENTIFIER: + if (func) { + func(&ts_current[-1]); + tk = ts_current[-1].tokentype; + } + break; + case '{': + level++; + break; + case '}': + level--; + break; + } + if (level <= 0) + break; + if (!(tk = lex())) + CError_ErrorTerm(102); + } while (1); + if (lookahead() == ';') { + tk = lex(); + count++; + } + } + + stream->tokens = count; + stream->firsttoken = galloc(count * sizeof(TStreamElement)); + memcpy(stream->firsttoken, ts_first + start_offset, count * sizeof(TStreamElement)); + cprep_eoltokens = save_eoltokens; +} + +void CPrep_StreamInsert(TStream *stream, SInt32 *state) { + if (ts_preread_elements + (ts_current - ts_first) + stream->tokens >= ts_elements) + CPrep_TSBufferGrow(stream->tokens); + if (ts_preread_elements) + memmove(ts_current + stream->tokens, ts_current, sizeof(TStreamElement) * ts_preread_elements); + memcpy(ts_current, stream->firsttoken, sizeof(TStreamElement) * stream->tokens); + ts_preread_elements += stream->tokens; + CPrep_TokenStreamGetState(state); +} + +void CPrep_StreamRemove(TStream *stream, SInt32 *state) { + TStreamElement *end; + SInt32 amount; + + end = ts_first + *state; + amount = ts_preread_elements + ((ts_current - ts_first) - *state - stream->tokens); + if (amount >= 0) { + if (amount) + memmove(end, end + stream->tokens, sizeof(TStreamElement) * amount); + ts_current = end; + ts_preread_elements = amount; + } +} + +void CPrep_RemoveTokens(SInt32 amount) { +#line 1296 + CError_ASSERT(ts_preread_elements >= amount); + + ts_preread_elements -= amount; + memmove(ts_current, ts_current + amount, sizeof(TStreamElement) * ts_preread_elements); +} + +void CPrep_TokenStreamFlush() { + if (!ts_preread_elements) + ts_current = ts_first; +} + +static int CPrep_TokenSize(char *str) { + int len; + int c; + + if ((str[0] >= 'a' && str[0] <= 'z') || (str[0] >= 'A' && str[0] <= 'Z') || (str[0] == '_')) { + len = 1; + str++; + do { + c = *(str++); + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || (c == '_')) + len++; + else + break; + } while (1); + return len; + } + + switch (str[0]) { + case '*': + if (str[1] == '=') return 2; + break; + case '/': + if (str[1] == '=' || str[1] == '*' || str[1] == '/') return 2; + break; + case '%': + if (str[1] == '=') return 2; + break; + case '+': + if (str[1] == '=' || str[1] == '+') return 2; + break; + case '-': + if (str[1] == '>') return (str[2] == '*') ? 3 : 2; + if (str[1] == '=' || str[1] == '-') return 2; + break; + case '<': + if (str[1] == '=') return 2; + if (str[1] == '<') return (str[2] == '=') ? 3 : 2; + break; + case '>': + if (str[1] == '=') return 2; + if (str[1] == '>') return (str[2] == '=') ? 3 : 2; + break; + case '&': + if (str[1] == '=' || str[1] == '&') return 2; + break; + case '^': + if (str[1] == '=') return 2; + break; + case '|': + if (str[1] == '=' || str[1] == '|') return 2; + break; + case '=': + if (str[1] == '=') return 2; + break; + case '!': + if (str[1] == '=') return 2; + break; + case '.': + if (str[1] == '.' && str[2] == '.') return 3; + if (str[1] == '*') return 2; + break; + case ':': + if (str[1] == ':') return 2; + break; + } + + return 1; +} + +TStreamElement *CPrep_CurStreamElement() { + static TStreamElement dummyelement; + if (ts_first < ts_current) + return ts_current - 1; + else + return &dummyelement; +} + +void CPrep_GetTokenContext(TStreamElement *token, CPrepFileInfo **tokenfile, SInt32 *selectionoffset, short *tokensize, SInt32 *plinenumber, char *buf1, short *tokenoffset, short *tokenlength, char *buf2, short *lastarg) { + // misassigned registers + SInt32 p; + TStreamElement *prevtoken; + char *filedata; + char *tokendata; + Boolean hasowndata; + SInt32 line; + SInt32 i; + char *r4; + int r5; + int r6; + char *r7; + char *r5x; + SInt16 c; + + if (token && !token->tokenfile) + token = NULL; + + prevtoken = token; + if (!token && ts_first < ts_current) + prevtoken = ts_current - 1; + + if (prevtoken && !prevtoken->tokenfile) { +#line 1454 + CError_FATAL(); + } + + if (was_prep_error || !prevtoken) { + if (!prep_file) + CError_CannotOpen(); + *tokenfile = prep_file; + if (!tokenstacklevel) { + p = pos - prep_file_start; + if (was_prep_error && p > 0) + p--; + } else { + p = tokenstack[0].pos - prep_file_start; + } + *selectionoffset = p; + } else { + *tokenfile = prevtoken->tokenfile; + p = prevtoken->tokenoffset; + *selectionoffset = p; + } + + filedata = (*tokenfile)->textbuffer; + if (!filedata) { + filedata = getfiledata(&(*tokenfile)->textfile); + hasowndata = 1; + } else { + hasowndata = 0; + } + + if (!cprep_hasprepline) { + line = 1; + for (i = 0; i < p; i++) { + if (filedata[i] == '\r') + line++; + } + *plinenumber = line; + } else { + *plinenumber = linenumber; + } -void CPrep_GetTokenContext(TStreamElement *token, CPrepFileInfo **tokenfile, SInt32 *selectionoffset, short *tokensize, SInt32 *linenumber, char *buf1, short *tokenoffset, short *tokenlength, char *buf2, short *lastarg) { + tokendata = filedata + p; + *tokensize = CPrep_TokenSize(tokendata); + if (!token && tokenstacklevel == 1) { + r4 = macrostart; + r7 = macropos; + } else { + r4 = filedata; + r7 = tokendata; + } + *tokenoffset = 0; + r5 = 1; + while (r5 < 80 && (r7 - r5) >= r4 && r7[-r5] != '\r') + r5++; + r5--; + while ((c = r7[-r5]) && (c == ' ' || c == '\t' || c == 4)) + r5--; + r6 = 0; + while ((c = r7[-r5]) != '\r' && c && r6 < 126) { + if (!r5) + *tokenoffset = r6; + if (c != 4) { + buf1[r6++] = (c != '\t') ? c : ' '; + } + r5--; + } + if (!r5) { + buf1[r6] = ' '; + *tokenoffset = r6; + buf1[r6 + 1] = 0; + *tokenlength = 1; + } else { + buf1[r6] = 0; + *tokenlength = CPrep_TokenSize(buf1 + *tokenoffset); + } + + if (p > 16) { + r5x = tokendata - 16; + *lastarg = 16; + } else { + r5x = filedata; + *lastarg = p; + } + for (i = 0; i < 31 && *r5x; i++) { + buf2[i] = *(r5x++); + } + buf2[i] = 0; + + if (hasowndata) + CWReleaseFileText(cparamblkptr->context, filedata); + was_prep_error = 0; } void CPrep_Error(short code) { @@ -685,16 +1266,281 @@ void popfile() { } } -static void prepoffset() {} -static void prepoffset2() {} -void CPrep_SetSourceFile() {} -void CPrep_GetSourceFilePath() {} -void CPrep_NewFileOffsetInfo() {} -void CPrep_GetFileOffsetInfo() {} -void CPrep_GetFileOffsetInfo2() {} -void CPrep_ResetFileInfo() {} -void CPrep_GetPrepPos() {} -Boolean C_Compiler(CParams *param) {} +static SInt32 prepoffset() { + if (filesp > 0) + return filestack[0]->pos; + else if (tokenstacklevel) + return tokenstack[0].pos - filestack[filesp]->textbuffer; + else + return pos - filestack[0]->textbuffer; +} + +static SInt32 prepoffset2() { + return lineoffset; +} + +void CPrep_SetSourceFile(FileOffsetInfo *foi) { + CPrepFileInfoList *list; + + if (foi->file) { + if (foi->file == filestack[0]) { + if (cprep_cursymfile) { + if (cparamblkptr->isPrecompiling != 1) + ObjGen_SrcBreakName(NULL, 0, 0); + cprep_cursymfile = NULL; + } + } else { + if (cprep_cursymfile != foi->file) { + for (list = cprep_files; list; list = list->next) { + if (foi->file == list->fileinfo) { + if (cparamblkptr->isPrecompiling != 1) + ObjGen_SrcBreakName(list->fileinfo->nameNode, list->fileinfo->fileModDate, 0); + cprep_cursymfile = foi->file; + return; + } + } + + list = galloc(sizeof(CPrepFileInfoList)); + list->next = cprep_files; + cprep_files = list; + list->fileinfo = foi->file; + if (cparamblkptr->isPrecompiling != 1) + ObjGen_SrcBreakName(list->fileinfo->nameNode, list->fileinfo->fileModDate, 1); + cprep_cursymfile = foi->file; + } + } + } +} + +HashNameNode *CPrep_GetSourceFilePath(CPrepFileInfo *fileinfo) { + HashNameNode *node; + if ((node = fileinfo->nameNode) == NULL) + node = CTool_GetPathName(&fileinfo->textfile, NULL); + return node; +} + +void CPrep_NewFileOffsetInfo(FileOffsetInfo *foi, TStreamElement *ts) { + if (!ts || !ts->tokenfile) { + if (ts_first < ts_current) { + foi->file = ts_current[-1].tokenfile; + foi->tokenline = ts_current[-1].tokenline; + foi->tokenoffset = ts_current[-1].tokenoffset; + } else { + foi->file = filestack[filesp]; + foi->tokenline = linenumber; + if (tokenstacklevel) + foi->tokenoffset = tokenstack[0].pos - filestack[filesp]->textbuffer; + else + foi->tokenoffset = pos - filestack[filesp]->textbuffer; + } + } else { + foi->file = ts->tokenfile; + foi->tokenline = ts->tokenline; + foi->tokenoffset = ts->tokenoffset; + } + foi->is_inline = 0; +} + +SInt32 CPrep_GetFileOffsetInfo(FileOffsetInfo *foi) { + SInt32 p; + SInt32 i; + + if (ts_first < ts_current && ts_current[-1].tokenfile == foi->file) { + if (ts_current[-1].tokenline > foi->tokenline) + foi->tokenline = ts_current[-1].tokenline; + if (ts_current[-1].tokenoffset > foi->tokenoffset) + foi->tokenoffset = ts_current[-1].tokenoffset; + } else if (foi->file == filestack[filesp]) { + if (linenumber > foi->tokenline) + foi->tokenline = linenumber; + if (tokenstacklevel) + p = tokenstack[0].pos - filestack[filesp]->textbuffer; + else + p = pos - filestack[filesp]->textbuffer; + if (p > foi->tokenoffset) + foi->tokenoffset = p; + } else { + for (i = filesp - 1; i >= 0; i--) { + if (foi->file == filestack[i]) { + if (filestack[i]->linenumber > foi->tokenline) + foi->tokenline = filestack[i]->linenumber; + if (filestack[i]->pos > foi->tokenoffset) + foi->tokenoffset = filestack[i]->pos; + break; + } + } + } + + return foi->tokenline; +} + +void CPrep_GetFileOffsetInfo2(FileOffsetInfo *foi, SInt32 *pLine, HashNameNode **pName) { + SInt32 p; + SInt32 i; + + if (ts_first < ts_current && ts_current[-1].tokenfile == foi->file) { + if (ts_current[-1].tokenline > foi->tokenline) + foi->tokenline = ts_current[-1].tokenline; + if (ts_current[-1].tokenoffset > foi->tokenoffset) + foi->tokenoffset = ts_current[-1].tokenoffset; + } else if (foi->file == filestack[filesp]) { + if (linenumber > foi->tokenline) + foi->tokenline = linenumber; + if (tokenstacklevel) + p = tokenstack[0].pos - filestack[filesp]->textbuffer; + else + p = pos - filestack[filesp]->textbuffer; + if (p > foi->tokenoffset) + foi->tokenoffset = p; + } else { + for (i = filesp - 1; i >= 0; i--) { + if (foi->file == filestack[i]) { + if (filestack[i]->linenumber > foi->tokenline) + foi->tokenline = filestack[i]->linenumber; + if (filestack[i]->pos > foi->tokenoffset) + foi->tokenoffset = filestack[i]->pos; + break; + } + } + } + + *pLine = foi->tokenline; +#line 2010 + CError_ASSERT(*pLine >= 0); + *pName = foi->file ? foi->file->nameNode : NULL; +} + +void CPrep_ResetFileInfo(FileOffsetInfo *foi) { + // this function is empty so i can only assume... +} + +void CPrep_GetPrepPos(CPrepFileInfo **file, SInt32 *ppos) { + *file = prep_file; + if (tokenstacklevel > 0) + *ppos = tokenstack->pos - prep_file_start; + else + *ppos = pos - prep_file_start; +} + +UInt8 C_Compiler(CParams *param) { + TStreamElement ts; + UInt8 code; + + CInt64_Init(); + cprep_packstackp = 128; + widestring = 0; + cprep_nomem_exit = 0; + cparamblkptr = param; + prep_file = NULL; + lines = 0; + linenumber = 0; + cprep_hasprepline = 0; + + if (CWDisplayLines(param->context, 0) != cwNoErr) + return 0; + + linetick = COS_GetTicks() + 5; + code = 0; + copts.delete_exception = 1; + copts.som_call_opt = 1; + copts.template_patch = 1; + copts.template_friends = 1; + copts.simple_class_byval = 1; + copts.array_new_delete = 1; + copts.syspath_once = 1; + copts.arg_dep_lookup = 1; + copts.longlong = 1; + copts.longlong_prepeval = copts.longlong; + copts.vbase_ctor_offset = 1; + copts.vbase_abi_v2 = 1; + copts.optEH = 1; + copts.optEH2 = 0; + if (copts.cplusplus) + copts.const_strings = 1; + copts.inline_bottom_up = 1; + + if (initheaps(&CError_NoMem)) { + releaseheaps(); + cprep_nomem_exit = 1; + code = 255; + } else { + if (setjmp(errorreturn) == 0) { + InitNameHash(); + setupprep(); + CParser_Setup(); + SetupPrecompiler(cparamblkptr->isPrecompiling); + SetupAssembler(); + ObjGen_Setup(); + PointerAnalysis_Setup(); + CBrowse_Setup(param); + + setupfile(NULL, 1, 0); + if (copts.oldprefixname[0]) + setupfile(copts.oldprefixname, 1, 0); + + coptssave = galloc(sizeof(COpts)); + *coptssave = copts; + coptpushs = NULL; + coptpush = NULL; + preprocessing_only = param->isPreprocessing; + if (param->isPreprocessing) + CPrep_Preprocess(); + else + cparser(); + + if (CWDisplayLines(param->context, lines) != cwNoErr) + anyerrors = 1; + + if (tokenstacklevel) { + was_prep_error = 1; + CError_ErrorTerm(119); + } else if (iflevel) { + was_prep_error = 0; + ts.tokenfile = ifstack[iflevel - 1].file; + ts.tokenoffset = ifstack[iflevel - 1].pos; + if (iflevel) + CError_SetErrorToken(&ts); + CError_ErrorTerm(119); + } + + if (!anyerrors) { + if (param->isPrecompiling == 1) { + CBrowse_Finish(param); + PrecompilerWrite(); + } else if (!param->isPreprocessing) { + ObjGen_Finish(); + CBrowse_Finish(param); + } + code = 1; + } + + if (param->isPreprocessing) { + cparamblkptr->objectDataHandle = pplist.data; + pplist.data = NULL; + cparamblkptr->browseDataHandle = NULL; + } + } else { + CWDisplayLines(param->context, lines); + } + + CParser_Cleanup(); + CleanupPrecompiler(); + CleanupAssembler(); + ObjGen_Cleanup(); + ObjGen_CodeCleanup(); + PointerAnalysis_Cleanup(); + cleanupprep(); + CBrowse_Cleanup(param); + } + + param->objectdata.compiledlines = lines; + if (cprep_nomem_exit) { + CompilerGetCString(7, string); + CWReportMessage(cparamblkptr->context, NULL, string, NULL, messagetypeError, 0); + } + + return code; +} static void pushtokenseq(Macro *macro) { if (tokenstacklevel >= 128) { @@ -723,24 +1569,504 @@ void poptokenseq() { spaceskip = 1; } -static void is_nextchar() {} -static void ismacroname() {} -static void ismacroname2() {} -static void ismacroname5() {} -static void ismacroname3() {} -static void ismacroname4() {} -void foundnl() {} -void newline() {} -static void gotonexttoken() {} -short notendofline() {} -static void CPrep_MacroRedefError() {} -static void goendofline() {} -static void CPrep_Define() {} -static void prepundefine() {} +static Boolean is_nextchar(short t) { + char *p = pos; + short level = tokenstacklevel; + int c; + + do { + switch ((c = *p)) { + case 0: + if (level <= 0) + return 0; + p = tokenstack[--level].pos; + continue; + case '\r': + p++; + continue; + } + if (c == t) + return 1; + if (c != ' ' && (c < 9 || c > 12)) + break; + p++; + } while (1); + + return 0; +} + +static Macro *ismacroname() { + Macro *scan; + Boolean save_macrocheck; + HashNameNode *name = tkidentifier; + + for (scan = macrohashtable[name->hashval]; scan; scan = scan->next) { + if (scan->name == name) { + if (scan->is_special) { + if (scan == &vecM && !copts.altivec_model) + return NULL; + if (scan == &stdcM && copts.cplusplus) + return NULL; + if (scan == &cpplM && !copts.cplusplus) + return NULL; + if (scan == &ecppM && (!copts.cplusplus || !copts.ecplusplus)) + return NULL; + } + + if (scan->xF) { + waslockedmacro = 1; + return NULL; + } + + if (scan->xC) { + save_macrocheck = macrocheck; + macrocheck = 0; + gotonexttoken(); + macrocheck = save_macrocheck; + if (*pos != '(') + return NULL; + } + + return scan; + } + } + + return NULL; +} + +static Macro *ismacroname2(char *str) { + Macro *scan; + HashNameNode *name = tkidentifier; + + for (scan = macrohashtable[name->hashval]; scan; scan = scan->next) { + if (scan->name == name) { + if (scan->xF) { + waslockedmacro = 1; + return NULL; + } + + if (scan->xC) { + while (*str == ' ' || (*str >= 9 && *str <= 12)) + str++; + if (*str != '(' && !is_nextchar('(')) + return NULL; + } + + return scan; + } + } + + return NULL; +} + +static Macro *ismacroname5(char *str) { + Macro *scan; + HashNameNode *name = tkidentifier; + + for (scan = macrohashtable[name->hashval]; scan; scan = scan->next) { + if (scan->name == name) { + if (scan->xF) { + waslockedmacro = 1; + return NULL; + } + + if (scan->xC) { + while (*str == ' ' || (*str >= 9 && *str <= 12)) + str++; + if (*str != '(') + return NULL; + } + + return scan; + } + } + + return NULL; +} + +static Macro *ismacroname3() { + Macro *scan; + HashNameNode *name = tkidentifier; + + for (scan = macrohashtable[name->hashval]; scan; scan = scan->next) { + if (scan->name == name) { + if (scan->is_special) { + if (scan == &vecM && !copts.altivec_model) + return NULL; + if (scan == &stdcM && copts.cplusplus) + return NULL; + if (scan == &cpplM && !copts.cplusplus) + return NULL; + } + break; + } + } + + return scan; +} + +static Macro *ismacroname4(HashNameNode *name) { + Macro *scan; + + for (scan = macrohashtable[name->hashval]; scan; scan = scan->next) { + if (scan->name == name) { + if (scan->is_special) { + if (scan == &vecM && !copts.altivec_model) + return NULL; + if (scan == &stdcM && copts.cplusplus) + return NULL; + if (scan == &cpplM && !copts.cplusplus) + return NULL; + } + break; + } + } + + return scan; +} + +void foundnl() { + if (!tokenstacklevel) { + if (preprocessing_only) + CPrep_PreprocessDumpNewLine(); + linenumber++; + lines++; + if (filesp <= 0) + lineoffset = pos - filestack[0]->textbuffer; + } +} + +void newline() { + foundnl(); + nlflag = 1; + at_linestart = 1; + spaceskip = 1; + if (COS_GetTicks() > linetick) { + if (CWDisplayLines(cparamblkptr->context, lines) != cwNoErr) + CError_UserBreak(); + linetick = COS_GetTicks() + 5; + } +} + +static void gotonexttoken() { + char *save_pos; + Macro *macro; + char c; + +loop: + switch ((c = prepskipnextchar())) { + case 0: + if (tokenstacklevel) { + poptokenseq(); + goto loop; + } + if (tokenstacklevel > 0 || pos >= prep_file_end) { + if (filesp > 0) { + popfile(); + goto loop; + } + return; + } + pos = nextcharpos; + goto loop; + case '\r': + newline(); + pos = nextcharpos; + goto loop; + } + + if (macrocheck && ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_'))) { + pos = ReadIdentifier(save_pos = pos); + if ((macro = ismacroname())) { + prepmacro(macro); + goto loop; + } else { + pos = save_pos; + } + } +} + +short notendofline() { + char *save_pos; + Macro *macro; + char c; + +loop: + switch ((c = prepskipnextchar())) { + case 0: + if (tokenstacklevel) { + poptokenseq(); + goto loop; + } + case '\r': + return 0; + } + + if (macrocheck && ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_'))) { + pos = ReadIdentifier(save_pos = pos); + if ((macro = ismacroname())) { + prepmacro(macro); + goto loop; + } else { + pos = save_pos; + } + } + + return 1; +} + +static void CPrep_MacroRedefError(char *name, Boolean *flag) { + if (!*flag) { + if (copts.gcc_extensions) { + CPrep_WarningName(108, name); + } else if (copts.cpp_extensions) { + if (copts.pedantic) + CPrep_WarningName(108, name); + } else { + CPrep_ErrorName(108, name); + } + *flag = 1; + } +} + +static void goendofline() { + if (notendofline()) { + CPrep_Error(113); + skipendofline(); + } +} + +static void CPrep_Define() { + Macro *existing_macro; // r31 + HashNameNode *name; // r29 + short r28; // r28 + Boolean r27; // r27 + Macro *macro; // r20 + short t; // r17 + Boolean error_flag; + + macrocheck = 0; + nlflag = 0; + t = lexidentifier(); + if (nlflag) { + CPrep_Error(112); + skipendofline(); + } + if (t != TK_IDENTIFIER) { + CPrep_Error(107); + skipendofline(); + return; + } + + macro = ismacroname3(); + name = tkidentifier; + error_flag = 0; + r27 = 0; + if (prepcurchar() == '(') { + r28 = 1; + pos = nextcharpos; + // fix me + } else { + macro = galloc(sizeof(Macro)); + r28 = 0; + } + + if (existing_macro && (existing_macro->xC & 0x7FFF) != r28) + CPrep_MacroRedefError(name->name, &error_flag); + + macro->name = name; + macro->xC = r27 ? (r28 | 0x8000) : r28; + macro->is_special = 0; + macro->xF = 0; + + if (r28 > 1) { + // fix me + } + + mlist.size = 0; + if (notendofline()) { + // fix me + } else { + // fix me + } +} + +static void prepundefine() { + short t; + Macro *macro; + Macro **scan; + HashNameNode *name; + + nlflag = 0; + t = lexidentifier(); + if (nlflag) { + CPrep_Error(112); + skipendofline(); + } else if (t != TK_IDENTIFIER) { + CPrep_Error(107); + skipendofline(); + } else { + name = tkidentifier; + for (scan = ¯ohashtable[name->hashval], macro = *scan; macro; scan = ¯o->next, macro = *scan) { + if (macro->name == name) { + *scan = macro->next; + macrocheck = 1; + return; + } + } + goendofline(); + } +} + static Boolean CPrep_CheckTarget() {} static Boolean CPrep_CheckOption() {} -static void CPrep_XpandDefinedCheck() {} -static void XpandString() {} +static char *CPrep_XpandDefinedCheck(char *) {} + +static char *XpandString(Macro *macro, char *somepos) { + // almost matches, r22 and r23 are swapped at the end + short start_level; + char *curpos; + char *tmp; + SInt32 tmplen; + SInt32 i; + char *macro_output; + Macro *macro2; + int c; + char *resultptr; + + pushtokenseq(macro); + macropos = somepos; + macrostart = somepos; + start_level = tokenstacklevel; + pos = somepos; + mlist.size = 0; + + while (tokenstacklevel >= start_level) { + loop: + switch (*(curpos = pos)) { + case 4: + AppendGListByte(&mlist, 4); + pos = ReadIdentifier(somepos = ++pos); + if (cprep_incondexpr && !strcmp(tkidentifier->name, "defined") && (tmp = CPrep_XpandDefinedCheck(pos))) + pos = tmp; + AppendGListData(&mlist, somepos, pos - somepos); + goto loop; + case '"': + case '\'': + somepos = pos++; + CPrep_MatchChar(*somepos, 0); + AppendGListData(&mlist, somepos, pos - somepos); + goto loop; + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': + case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': + case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': + case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': + case '_': + pos = ReadIdentifier(curpos); + waslockedmacro = 0; + if (cprep_incondexpr && !strcmp(tkidentifier->name, "defined") && (tmp = CPrep_XpandDefinedCheck(pos))) { + pos = tmp; + AppendGListData(&mlist, curpos, pos - curpos); + goto loop; + } else { + if (macro) + macro2 = ismacroname2(pos); + else + macro2 = ismacroname5(pos); + if (macro2) { + AppendGListByte(&mlist, 5); + tmplen = mlist.size; + if (tmplen > 0x20000) { + macropos = pos; + CPrep_Error(111); + return ""; + } + curpos = aalloc(tmplen); + memcpy(curpos, *mlist.data, tmplen); + macro_output = XpandMacro(macro2); + if (tokenstacklevel == start_level) { + for (i = strlen(macro_output) - 1; i > 0; i--) { + switch (macro_output[i]) { + case ' ': + case '"': + case '\'': + case ';': + goto exit_innermost_loop; + } + } + exit_innermost_loop: + if (i > 0) { + mlist.size = 0; + AppendGListName(&mlist, ¯o_output[i + 1]); + AppendGListID(&mlist, pos); + pos = aalloc(mlist.size); + memcpy(pos, *mlist.data, mlist.size); + mlist.size = 0; + AppendGListData(&mlist, curpos, tmplen); + AppendGListData(&mlist, macro_output, i + 1); + } else { + mlist.size = 0; + AppendGListName(&mlist, macro_output); + AppendGListID(&mlist, pos); + macro_output = aalloc(mlist.size); + memcpy(macro_output, *mlist.data, mlist.size); + mlist.size = 0; + pos = macro_output; + AppendGListData(&mlist, curpos, tmplen); + } + } else { + mlist.size = 0; + AppendGListData(&mlist, curpos, tmplen); + AppendGListID(&mlist, macro_output); + if (tokenstacklevel < start_level) + goto skip_null_term; + mlist.size--; + goto loop; + } + } else { + if (waslockedmacro) + AppendGListByte(&mlist, 4); + AppendGListData(&mlist, curpos, pos - curpos); + goto loop; + } + } + break; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + AppendGListByte(&mlist, *(pos++)); + do { + c = *pos; + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c >= '0' && c <= '9')) { + AppendGListByte(&mlist, c); + pos++; + } else { + break; + } + } while (1); + goto loop; + default: + AppendGListByte(&mlist, *(pos++)); + goto loop; + case 0: + if (tokenstacklevel >= start_level) + poptokenseq(); + } + } + + AppendGListByte(&mlist, 0); +skip_null_term: + if ((tmplen = mlist.size) > 0x20000) { + CPrep_Error(111); + return ""; + } else { + resultptr = aalloc(tmplen); + memcpy(resultptr, *mlist.data, tmplen); + return resultptr; + } +} + char *CPrep_GetFileName(char *buffer, Boolean flag1, Boolean flag2) { } @@ -795,22 +2121,364 @@ static char *XpandSpecialMacro(Macro *macro) { } } -static void XpandMacro() {} -static void prepmacro() {} -void macrotest() {} -void CPrep_PragmaLex() {} -void CPrep_PushOption() {} -void CPrep_PopOption() {} -static void CPrep_PragmaImExport() {} -static void pragma_on_off_reset() {} -static void CPrep_PragmaOnceName() {} -static void pragma_precompile_target() {} -static void CPrep_DefinePragmaOnceMacro() {} -static void CPrep_PragmaOnce() {} -static void CPrep_PragmaUnused() {} -static void CPrep_PragmaInlineDepth() {} -static void CPrep_PragmaInlineMaxSize() {} -static void CPrep_PragmaInlineMaxTotalSize() {} +static char *XpandMacro(Macro *macro) { +} + +static void prepmacro(Macro *macro) { + Boolean save_spaceskip; + char *result; + + macrocheck = 0; + dofreeaheap = 0; + save_spaceskip = spaceskip; + result = XpandMacro(macro); + macrocheck = 1; + pushtokenseq(NULL); + macropos = result; + pos = result; + macrostart = result; + dofreeaheap = 1; + macrocheck = 0; + spaceskip = save_spaceskip; +} + +Boolean macrotest() { + Macro *macro; + if ((macro = ismacroname())) { + prepmacro(macro); + return 1; + } else { + return 0; + } +} + +short CPrep_PragmaLex(Boolean no_err) { + if (notendofline()) + return plex(); + if (!no_err) + CPrep_Error(113); + return 0; +} + +void CPrep_PushOption(SInt32 id, char value) { + struct COptPush *opt; + struct COptPush *newopt; + + opt = coptpush; + do { + if (!opt || (opt->x8 && opt->id == id)) { + newopt = galloc(sizeof(struct COptPush)); + newopt->next = coptpush; + coptpush = opt = newopt; + break; + } + if (!opt->x8) + break; + opt = opt->next; + } while (1); + + opt->value = ((UInt8 *) &copts)[id]; + opt->id = id; + opt->x8 = 1; + ((UInt8 *) &copts)[id] = value; +} + +void CPrep_PopOption(SInt32 id) { + struct COptPush *opt; + + for (opt = coptpush; opt; opt = opt->next) { + if (opt->x8 && opt->id == id) { + ((UInt8 *) &copts)[id] = opt->value; + opt->x8 = 0; + return; + } + } + + ((UInt8 *) &copts)[id] = ((UInt8 *) coptssave)[id]; +} + +static void CPrep_PragmaImExport(int flags) { + // does not match - weirdness with the branching inside the loop + NameSpaceObjectList *list; + + do { + if (!notendofline()) + break; + if (plex() != TK_IDENTIFIER) + break; + + if (!(list = CScope_GetLocalObject(cscope_root, tkidentifier))) { + break; + } else { + while (list) { + if (list->object->otype == OT_OBJECT) { + switch (OBJECT(list->object)->datatype) { + case DDATA: + case DFUNC: + OBJECT(list->object)->flags |= flags; + break; + default: + CPrep_Warning(186); + return; + } + } + list = list->next; + } + } + + if (!notendofline()) + return; + } while (plex() == ',' && notendofline()); + + if (copts.warn_illpragma) + CPrep_Warning(186); +} + +static void pragma_on_off_reset(UInt32 bits) { + Boolean flag = (bits & OPT_FLAG_2000) != 0; + int imex_flags; + + if (notendofline() && plex() == TK_IDENTIFIER) { + if (!strcmp(tkidentifier->name, "on")) { + CPrep_PushOption(bits & OPT_OFFSET_MASK, 1); + return; + } + if (!strcmp(tkidentifier->name, "off")) { + CPrep_PushOption(bits & OPT_OFFSET_MASK, 0); + return; + } + if (!strcmp(tkidentifier->name, "reset")) { + CPrep_PopOption(bits & OPT_OFFSET_MASK); + return; + } + if (flag && !strcmp(tkidentifier->name, "list")) { + if (cparamblkptr->isPreprocessing) { + skipendofline(); + return; + } + + macrocheck = 1; + if ((bits & OPT_OFFSET_MASK) == OPT_OFFSET(internal)) + imex_flags = OBJECT_FLAGS_10; + else if ((bits & OPT_OFFSET_MASK) == OPT_OFFSET(import)) + imex_flags = OBJECT_FLAGS_20; + else if ((bits & OPT_OFFSET_MASK) == OPT_OFFSET(export)) + imex_flags = OBJECT_FLAGS_40; + else if ((bits & OPT_OFFSET_MASK) == OPT_OFFSET(lib_export)) + imex_flags = OBJECT_FLAGS_60; + else +#line 3610 + CError_FATAL(); + CPrep_PragmaImExport(imex_flags); + return; + } + } + + if (copts.warn_illpragma) + CPrep_Warning(186); +} + +static HashNameNode *CPrep_PragmaOnceName(StringPtr name, Boolean flag) { + // does not match, can't be bothered to fix it atm + short len; + char myname[256]; + unsigned char *src; + char *dst; + + len = name[0]; + if (len > 250) + len = 250; + + dst = &myname[1]; + src = &name[1]; + while (len-- > 0) { + *(dst++) = tolower(*(src++)); + } + *dst = 0; + + myname[0] = (copts.syspath_once && flag) ? '$' : -'\\'; + return GetHashNameNodeExport(myname); +} + +static void pragma_precompile_target() { + if (!notendofline()) { + CPrep_Error(112); + return; + } + + if (plex() != TK_STRING) { + CPrep_Error(117); + skipendofline(); + return; + } + + if (ispascalstring) { + CPrep_Error(101); + skipendofline(); + return; + } + + precomp_target_str = tkstring; + goendofline(); +} + +static void CPrep_DefinePragmaOnceMacro(StringPtr name, Boolean flag) { + HashNameNode *namenode; + Macro *macro; + + namenode = CPrep_PragmaOnceName(name, flag); + if (!ismacroname4(namenode)) { + macro = galloc(sizeof(Macro)); + memclrw(macro, sizeof(Macro)); + macro->name = namenode; + macro->next = macrohashtable[namenode->hashval]; + macrohashtable[namenode->hashval] = macro; + } +} + +static void CPrep_PragmaOnce() { + if (notendofline()) { + if (plex() == TK_IDENTIFIER) { + if (!strcmp(tkidentifier->name, "on")) { + include_once = 1; + return; + } else if (!strcmp(tkidentifier->name, "off")) { + include_once = 0; + return; + } + } + if (copts.warn_illpragma) + CPrep_Warning(186); + } else { + Str255 filename; + COS_FileGetFSSpecInfo(&prep_file->textfile, NULL, NULL, filename); + CPrep_DefinePragmaOnceMacro(filename, prep_file->unkfield126); + } +} + +static void CPrep_PragmaUnused() { + NameSpace *nspace; + NameSpaceObjectList *list; + short t; + + if (cparamblkptr->isPreprocessing) { + skipendofline(); + return; + } + + if (cscope_currentfunc && notendofline() && plex() == '(' && notendofline()) { + restart: + if (plex() == TK_IDENTIFIER) { + for (nspace = cscope_current; nspace; nspace = nspace->parent) { + if (nspace->is_global) + break; + + list = CScope_GetLocalObject(nspace, tkidentifier); + if (list && list->object->otype == OT_OBJECT && OBJECT(list->object)->datatype == DLOCAL) { + OBJECT(list->object)->flags |= OBJECT_FLAGS_UNUSED; + if (notendofline()) { + t = plex(); + if (t == ')') + return; + if (t == ',' && notendofline()) + goto restart; + } + break; + } + } + } + } + + if (copts.warn_illpragma) + CPrep_Warning(186); +} + +static void CPrep_PragmaInlineDepth() { + int lv; + + if (notendofline() && plex() == '(' && notendofline()) { + switch (plex()) { + case TK_IDENTIFIER: + if (strcmp(tkidentifier->name, "smart")) + CPrep_Warning(186); + else + copts.inlinelevel = 0; + break; + case TK_INTCONST: + lv = CInt64_GetULong(&tkintconst); + if (lv >= 0 && lv <= 1024) + copts.inlinelevel = lv ? lv : -1; + else + CPrep_Warning(186); + break; + default: + CPrep_Warning(186); + skipendofline(); + return; + } + + if (!notendofline() || plex() != ')') { + CPrep_Warning(115); + } + if (notendofline()) { + CPrep_Warning(113); + skipendofline(); + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + } +} + +static void CPrep_PragmaInlineMaxSize() { + if (notendofline() && plex() == '(' && notendofline()) { + switch (plex()) { + case TK_INTCONST: + copts.inline_max_size = CInt64_GetULong(&tkintconst); + break; + default: + CPrep_Warning(186); + skipendofline(); + return; + } + + if (!notendofline() || plex() != ')') { + CPrep_Warning(115); + } + if (notendofline()) { + CPrep_Warning(113); + skipendofline(); + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + } +} + +static void CPrep_PragmaInlineMaxTotalSize() { + if (notendofline() && plex() == '(' && notendofline()) { + switch (plex()) { + case TK_INTCONST: + copts.inline_max_total_size = CInt64_GetULong(&tkintconst); + break; + default: + CPrep_Warning(186); + skipendofline(); + return; + } + + if (!notendofline() || plex() != ')') { + CPrep_Warning(115); + } + if (notendofline()) { + CPrep_Warning(113); + skipendofline(); + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + } +} static void pragma_segment() { short i; @@ -841,7 +2509,40 @@ static void pragma_segment() { } } -static void pragma_options() {} +static void pragma_options() { + if (notendofline() && plex() == TK_IDENTIFIER && !strcmp(tkidentifier->name, "align") && notendofline() && plex() == '=' && notendofline() && plex() == TK_IDENTIFIER) { + if (!strcmp(tkidentifier->name, "reset")) { + CPrep_PopOption(OPT_OFFSET(align_mode)); + goto done; + } else if (!strcmp(tkidentifier->name, "native")) { + CPrep_PushOption(OPT_OFFSET(align_mode), AlignMode2_PPC); + goto done; + } else if (!strcmp(tkidentifier->name, "mac68k")) { + CPrep_PushOption(OPT_OFFSET(align_mode), AlignMode0_Mac68k); + goto done; + } else if (!strcmp(tkidentifier->name, "mac68k4byte")) { + CPrep_PushOption(OPT_OFFSET(align_mode), AlignMode1_Mac68k4byte); + goto done; + } else if (!strcmp(tkidentifier->name, "power")) { + CPrep_PushOption(OPT_OFFSET(align_mode), AlignMode2_PPC); + goto done; + } else if (!strcmp(tkidentifier->name, "packed")) { + CPrep_PushOption(OPT_OFFSET(align_mode), AlignMode8_Packed); + goto done; + } + } + + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + return; + +done: + if (notendofline()) { + CPrep_Error(113); + skipendofline(); + } +} static void pragma_push() { struct COptsPush *push; @@ -863,35 +2564,1120 @@ static void pragma_pop() { } } -static void pragma_overload() {} -static void pragma_optimization_level() {} -static void pragma_opt_unroll_count() {} -static void pragma_opt_unroll_instr_count() {} -static void pragma_pack() {} -static void pragma_comment() {} -static void pragma_message() {} -static void preppragma() {} -static void prepinclude() {} -static void prepline() {} -static void CPrep_GetPrepType() {} -static void CPrep_ParseUnary() {} -static void CPrep_ParseBinary() {} -static void CPrep_ParseCond() {} -static void doevalconstexpr() {} -static void pushifstate() {} -static void popifstate() {} -static void positiveif() {} -static void negativeif() {} -static void prepif() {} -static void prepifdef() {} -static void prepifndef() {} -static void prepelif() {} -static void prepelse() {} -static void prependif() {} -static void prepifskip() {} -void preprocessor() {} -void CPrep_BrowserTokenOffset() {} -void CPrep_BrowserFileOffset() {} +static void pragma_overload() { + Object *obj; + + if (cparamblkptr->isPreprocessing) { + skipendofline(); + return; + } + + nlflag = 0; + tk = lex(); + if ((obj = CParser_ParseObject())) { + if (obj->sclass && obj->sclass != 0x103) + CPrep_Error(177); + obj->qual |= Q_OVERLOAD; + } else { + CPrep_Error(186); + } + + if (nlflag) + CPrep_Error(112); + if (tk != ';') + CPrep_Error(123); +} + +static void pragma_optimization_level() { + short t; + int lv; + + if (notendofline()) { + t = plex(); + if (t == TK_INTCONST) { + lv = CInt64_GetULong(&tkintconst); + if (lv >= 0 && lv <= 4) { + if (copts.crippled && lv > 1) { + CPrep_Warning(385); + lv = 1; + } + CPrep_PushOption(OPT_OFFSET(optimizationlevel), lv); + CodeGen_UpdateOptimizerOptions(); + CodeGen_UpdateBackEndOptions(); + } else { + CPrep_Error(154); + skipendofline(); + } + } else if (t == TK_IDENTIFIER && !strcmp(tkidentifier->name, "reset")) { + CPrep_PopOption(OPT_OFFSET(optimizationlevel)); + CodeGen_UpdateOptimizerOptions(); + CodeGen_UpdateBackEndOptions(); + } else { + CPrep_Error(105); + skipendofline(); + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + } +} + +static void pragma_opt_unroll_count() { + short t; + int lv; + + if (notendofline()) { + t = plex(); + if (t == TK_INTCONST) { + lv = CInt64_GetULong(&tkintconst); + if (lv >= 0 && lv <= 127) { + CPrep_PushOption(OPT_OFFSET(loop_unroll_count), lv); + CodeGen_UpdateOptimizerOptions(); + CodeGen_UpdateBackEndOptions(); + } else { + CPrep_Error(154); + skipendofline(); + } + } else if (t == TK_IDENTIFIER && !strcmp(tkidentifier->name, "reset")) { + CPrep_PopOption(OPT_OFFSET(loop_unroll_count)); + CodeGen_UpdateOptimizerOptions(); + CodeGen_UpdateBackEndOptions(); + } else { + CPrep_Error(105); + skipendofline(); + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + } +} + +static void pragma_opt_unroll_instr_count() { + short t; + int lv; + + if (notendofline()) { + t = plex(); + if (t == TK_INTCONST) { + lv = CInt64_GetULong(&tkintconst); + if (lv >= 0 && lv <= 127) { + CPrep_PushOption(OPT_OFFSET(loop_unroll_size_threshold), lv); + CodeGen_UpdateOptimizerOptions(); + CodeGen_UpdateBackEndOptions(); + } else { + CPrep_Error(154); + skipendofline(); + } + } else if (t == TK_IDENTIFIER && !strcmp(tkidentifier->name, "reset")) { + CPrep_PopOption(OPT_OFFSET(loop_unroll_size_threshold)); + CodeGen_UpdateOptimizerOptions(); + CodeGen_UpdateBackEndOptions(); + } else { + CPrep_Error(105); + skipendofline(); + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + } +} + +static void pragma_pack() { + int t; + int i; + Boolean did_push; + Boolean did_pop; + + if (notendofline() && plex() == '(') { + macrocheck = 1; + if (notendofline() && ((t = plex()) == ')')) { + copts.align_mode = coptssave->align_mode; + } else { + did_push = did_pop = 0; + do { + if (t == TK_IDENTIFIER) { + if (!strcmp(tkidentifier->name, "push")) { + if (cprep_packstackp) { + cprep_packstackp--; + cprep_packstack[cprep_packstackp].identifier = NULL; + cprep_packstack[cprep_packstackp].align_mode = copts.align_mode; + did_push = 1; + } else { + CPrep_Warning(186); + } + } else if (!strcmp(tkidentifier->name, "pop")) { + if (cprep_packstackp < 128) { + copts.align_mode = cprep_packstack[cprep_packstackp].align_mode; + cprep_packstackp++; + did_pop = 1; + } else { + CPrep_Warning(186); + } + } else { + if (did_push) { + cprep_packstack[cprep_packstackp].identifier = tkidentifier; + } else if (did_pop) { + for (i = cprep_packstackp - 1; i < 128; i++) { + if (cprep_packstack[i].identifier == tkidentifier) + break; + } + if (i < 128) { + copts.align_mode = cprep_packstack[i].align_mode; + cprep_packstackp = i + 1; + } else { + CPrep_Warning(186); + } + } else { + CPrep_Warning(186); + } + did_pop = 0; + did_push = 0; + } + } else { + if (t == TK_INTCONST) { + switch (CInt64_GetULong(&tkintconst)) { + case 0: + copts.align_mode = coptssave->align_mode; + break; + case 1: + copts.align_mode = AlignMode3_1Byte; + break; + case 2: + copts.align_mode = AlignMode4_2Byte; + break; + case 4: + copts.align_mode = AlignMode5_4Byte; + break; + case 8: + copts.align_mode = AlignMode6_8Byte; + break; + case 16: + copts.align_mode = AlignMode7_16Byte; + break; + default: + if (copts.warn_illpragma) + CPrep_Warning(186); + } + } + did_pop = 0; + did_push = 0; + } + + if (notendofline()) + t = plex(); + if (t != ',') + break; + t = plex(); + } while (1); + } + if (t != ')' && copts.warn_illpragma) + CPrep_Warning(186); + macrocheck = 0; + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + } +} + +static void pragma_comment() { + int t; + short start_tokenstacklevel = tokenstacklevel; + + if (notendofline() && plex() == '(') { + if (notendofline()) { + t = plex(); + if (t == TK_IDENTIFIER) { + if (!strcmp(tkidentifier->name, "compiler")) { + t = plex(); + } else if (!strcmp(tkidentifier->name, "exestr") || !strcmp(tkidentifier->name, "linker") || !strcmp(tkidentifier->name, "user")) { + if (plex() == ',') { + macrocheck = 1; + t = plex(); + macrocheck = 0; + if (t == TK_STRING) { + while (t == TK_STRING) { + macrocheck = 1; + if (tokenstacklevel == start_tokenstacklevel && !notendofline()) + break; + macrocheck = 1; + t = plex(); + macrocheck = 0; + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + return; + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + return; + } + } else if (!strcmp(tkidentifier->name, "lib")) { + if (plex() == ',') { + macrocheck = 1; + t = plex(); + macrocheck = 0; + if (t == TK_STRING) { + while (t == TK_STRING) { + macrocheck = 1; + if (tokenstacklevel == start_tokenstacklevel && !notendofline()) + break; + macrocheck = 1; + t = plex(); + macrocheck = 0; + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + return; + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + return; + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + return; + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + return; + } + } + + if (t != ')') { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + } +} + +static void pragma_message() { + int t; + short start_tokenstacklevel; + char str[128]; + char *ptr; + + if (notendofline() && plex() == '(') { + if (notendofline()) { + start_tokenstacklevel = tokenstacklevel; + ptr = str; + str[0] = 0; + macrocheck = 1; + t = plex(); + macrocheck = 0; + if (t == TK_STRING) { + while (t == TK_STRING) { + strncpy(ptr, tkstring, sizeof(str) - (ptr - str)); + str[sizeof(str) - 1] = 0; + ptr = str + strlen(str); + + macrocheck = 1; + if (tokenstacklevel == start_tokenstacklevel && !notendofline()) + break; + macrocheck = 1; + t = plex(); + macrocheck = 0; + } + + CWReportMessage(cparamblkptr->context, NULL, str, NULL, messagetypeInfo, 337); + skipendofline(); + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + } + } else if (plex() != ')') { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + } +} + +static void preppragma() { + struct CompilerOption *opt; + Boolean save_eoltokens; + + if (notendofline()) { + macrocheck = 0; + if (lexidentifier() == TK_IDENTIFIER) { + if (!strcmp(tkidentifier->name, "pack")) { + pragma_pack(); + } else if (!strcmp(tkidentifier->name, "optimization_level")) { + pragma_optimization_level(); + } else if (!strcmp(tkidentifier->name, "once")) { + CPrep_PragmaOnce(); + } else if (!strcmp(tkidentifier->name, "unused")) { + CPrep_PragmaUnused(); + } else if (!strcmp(tkidentifier->name, "inline_depth")) { + CPrep_PragmaInlineDepth(); + } else if (!strcmp(tkidentifier->name, "inline_max_size")) { + CPrep_PragmaInlineMaxSize(); + } else if (!strcmp(tkidentifier->name, "inline_max_total_size")) { + CPrep_PragmaInlineMaxTotalSize(); + } else if (!strcmp(tkidentifier->name, "opt_pointer_analysis_mode")) { + PointerAnalysis_PragmaMode(); + } else if (!strcmp(tkidentifier->name, "options")) { + pragma_options(); + macrocheck = 1; + return; + } else if (!strcmp(tkidentifier->name, "segment")) { + pragma_segment(); + } else if (!strcmp(tkidentifier->name, "push")) { + pragma_push(); + } else if (!strcmp(tkidentifier->name, "pop")) { + pragma_pop(); + } else if (!strcmp(tkidentifier->name, "parameter")) { + macrocheck = 1; + CMach_PragmaParams(); + } else if (!strcmp(tkidentifier->name, "overload")) { + macrocheck = 1; + pragma_overload(); + } else if (!strcmp(tkidentifier->name, "mark")) { + skipendofline(); + macrocheck = 1; + return; + } else if (!strcmp(tkidentifier->name, "precompile_target")) { + pragma_precompile_target(); + } else if (!strcmp(tkidentifier->name, "message")) { + pragma_message(); + } else if (!strcmp(tkidentifier->name, "opt_unroll_count")) { + pragma_opt_unroll_count(); + } else if (!strcmp(tkidentifier->name, "opt_unroll_instr_count")) { + pragma_opt_unroll_instr_count(); + } else if (!strcmp(tkidentifier->name, "exception_terminate")) { + if (!preprocessing_only) + CExcept_Terminate(); + } else if (!strcmp(tkidentifier->name, "exception_arrayinit")) { + if (!preprocessing_only) + CExcept_ArrayInit(); + } else if (!strcmp(tkidentifier->name, "exception_magic")) { + if (!preprocessing_only) + CExcept_Magic(); + } else if (!strcmp(tkidentifier->name, "SOMReleaseOrder")) { + macrocheck = 1; + CSOM_PragmaReleaseOrder(); + } else if (!strcmp(tkidentifier->name, "SOMClassVersion")) { + macrocheck = 1; + CSOM_PragmaClassVersion(); + } else if (!strcmp(tkidentifier->name, "SOMMetaClass")) { + macrocheck = 1; + CSOM_PragmaMetaClass(); + } else if (!strcmp(tkidentifier->name, "SOMCallStyle")) { + CSOM_PragmaCallStyle(); + } else { + for (opt = compileroptions; opt->name; opt++) { + if (!strcmp(tkidentifier->name, opt->name) && !(opt->bits & OPT_FLAG_4000)) { + pragma_on_off_reset(opt->bits); + if (opt->bits & OPT_FLAG_8000) + CMach_Configure(); + goto foundOption; + } + } + + save_eoltokens = cprep_eoltokens; + cprep_eoltokens = 1; + CodeGen_ParsePragma(tkidentifier); + cprep_eoltokens = save_eoltokens; + macrocheck = 1; + return; + } + } else { + if (copts.warn_illpragma) + CPrep_Warning(186); + skipendofline(); + macrocheck = 1; + return; + } + foundOption: + if (notendofline()) { + CPrep_Error(113); + skipendofline(); + } + CPrep_Reconfig(); + macrocheck = 1; + } +} + +static void prepinclude(Boolean flag) { + // mostly ok but registers need to be rearranged + short t; + Boolean r29; + short len; + short i; + char *save_pos; + char buf[256]; + short start_tokenstacklevel; + StringPtr ptr; + + if (!notendofline()) { + CPrep_Error(112); + return; + } + + t = prepcurchar(); + if (t != '"' && t != '<') { + CPrep_Error(117); + skipendofline(); + return; + } + + r29 = 1; + save_pos = pos; + if (t == '<') { + prepnextchar(); + if (!copts.flat_include) + r29 = 0; + len = 0; + while ((t = prepnextstringchar(save_pos, 1)) != '>') { + if (t != 5) { + if (len > 254) { + CPrep_Error(106); + skipendofline(); + return; + } + buf[++len] = t; + } + } + buf[0] = len; + ptr = (StringPtr) buf; + } else { + start_tokenstacklevel = tokenstacklevel; + macrocheck = 1; + t = plex(); + macrocheck = 0; + buf[1] = 0; + if (t != TK_STRING) { + CPrep_Error(117); + skipendofline(); + return; + } + + while (t == TK_STRING) { + strncat(&buf[1], tkstring, 254 - strlen(&buf[1])); + buf[255] = 0; + if (tokenstacklevel == start_tokenstacklevel && !notendofline()) + break; + macrocheck = 1; + t = plex(); + macrocheck = 0; + } + buf[0] = strlen(&buf[1]); + ptr = (StringPtr) buf; + } + + goendofline(); + if (ismacroname4(CPrep_PragmaOnceName((StringPtr) buf, !r29))) + return; + if (flag || copts.always_import) + CPrep_DefinePragmaOnceMacro((StringPtr) buf, !r29); + + if (copts.flat_include) { + for (i = len; i > 0; i--) { + switch (buf[i]) { + case ':': + case '/': + case '\\': + ptr = (StringPtr) buf; + ptr += i; + buf[i] = len - i; + goto all_done; + } + } + } + +all_done: + setupfile(ptr, r29, flag); +} + +static void prepline() { + short t; + short len; + char buf[256]; + + cprep_hasprepline = 1; + if (!notendofline()) { + CPrep_Error(112); + return; + } + + if (plex() != TK_INTCONST) { + CPrep_Error(117); + skipendofline(); + return; + } + + linenumber = CInt64_GetULong(&tkintconst) - 1; + if (notendofline()) { + if (prepnextchar() != '"') { + CPrep_Error(117); + skipendofline(); + return; + } + + len = 0; + while ((t = prepnextchar()) != '"') { + if (!t) + break; + if (len > 252) { + CPrep_Error(106); + skipendofline(); + return; + } + buf[len] = t; + len++; + } + buf[len] = 0; + + CTool_CtoPstr(buf); + filestack[filesp]->nameNode = CPrep_GetSourceFilePath(filestack[filesp]); + COS_FileSetFSSpec(&filestack[filesp]->textfile, (StringPtr) buf); + goendofline(); + if (preprocessing_only && !copts.simple_prepdump) + CPrep_PreprocessDumpFileInfo(0); + } +} + +static TypeIntegral *CPrep_GetPrepType(PrepValue *pv) { + if (copts.longlong_prepeval || copts.c9x) { + if (pv->is_unsigned) + return &stunsignedlonglong; + else + return &stsignedlonglong; + } else { + if (pv->is_unsigned) + return &stunsignedlong; + else + return &stsignedlong; + } +} + +static PrepValue CPrep_ParseUnary() { + +} + +static PrepValue CPrep_ParseBinary(PrepValue *rhs, short op) { + // i need a lot of fixing :( + PrepValue a; + PrepValue b; + short t; + short op2; + short op3; + short prec2; + short prec3; + + if (!rhs) { + a = CPrep_ParseUnary(); + } else { + a = *rhs; + } + + op2 = op; +restart: + op3 = exprtk; + prec3 = GetPrec(op3); + if (!prec3) { + return a; + } + if (!notendofline()) { + CPrep_Error(112); + return a; + } + b = CPrep_ParseUnary(); + prec3 = prec3; // variable change situation? + do { + if (exprtk == ')' || !notendofline()) { + if (b.is_unsigned) + a.is_unsigned = 1; + a.val = CMach_CalcIntDiadic((Type *) CPrep_GetPrepType(&a), a.val, t, b.val); + return a; + } + + op = GetPrec(exprtk); + if (!op) { + CPrep_Error(141); + return a; + } + if (prec3 >= prec2) { + if (b.is_unsigned) + a.is_unsigned = 1; + a.val = CMach_CalcIntDiadic((Type *) CPrep_GetPrepType(&a), a.val, t, b.val); + if (GetPrec(op) > op2) + goto restart; + return a; + } + b = CPrep_ParseBinary(&b, prec3); + } while (1); +} + +static PrepValue CPrep_ParseCond() { + PrepValue a; + PrepValue b; + PrepValue c; + + a = CPrep_ParseBinary(NULL, -1); + if (exprtk == '?') { + b = CPrep_ParseCond(); + if (!notendofline()) { + CPrep_Error(112); + return a; + } + if (exprtk != ':') { + CPrep_Error(170); + return a; + } + if (!notendofline()) { + CPrep_Error(112); + return a; + } + c = CPrep_ParseCond(); + a = !CInt64_IsZero(&a.val) ? b : c; + } + + return a; +} + +static void doevalconstexpr() { + PrepValue v; + + macrocheck = 1; + nlflag = 0; + cprep_incondexpr = 1; + v = CPrep_ParseCond(); + if (exprtk) + CPrep_Error(141); + cprep_incondexpr = 0; + if (nlflag) + CPrep_Error(112); + else + goendofline(); + tkintconst = v.val; +} + +static void pushifstate(SInt16 state) { + if (iflevel >= 64) { + CPrep_Error(215); + } else { + ifstack[iflevel].state = state; + ifstack[iflevel].file = prep_file; + ifstack[iflevel].pos = pos - prep_file_start; + iflevel++; + } +} + +static void popifstate() { + if (iflevel <= 0) { + CPrep_Error(117); + } else { + switch (ifstack[iflevel - 1].state) { + case IfState_1: + case IfState_3: + case IfState_4: + iflevel--; + return; + } + + iflevel--; + if (iflevel > 0) { + switch (ifstack[iflevel - 1].state) { + case IfState_1: + case IfState_3: + case IfState_4: + prepifskip(); + } + } + } +} + +static void positiveif() { + pushifstate(IfState_0); +} + +static void negativeif(Boolean flag) { + if (flag) { + pushifstate(IfState_1); + prepifskip(); + } else { + pushifstate(IfState_3); + } +} + +static void prepif() { + if (iflevel > 0) { + switch (ifstack[iflevel - 1].state) { + case IfState_1: + case IfState_3: + case IfState_4: + skipendofline(); + negativeif(0); + return; + } + } + + doevalconstexpr(); + if (CInt64_IsZero(&tkintconst)) + negativeif(1); + else + positiveif(); +} + +static void prepifdef() { + if (iflevel > 0) { + switch (ifstack[iflevel - 1].state) { + case IfState_1: + case IfState_3: + case IfState_4: + skipendofline(); + negativeif(0); + return; + } + } + + macrocheck = 0; + if (!notendofline()) { + CPrep_Error(112); + negativeif(1); + return; + } + + if (lexidentifier() != TK_IDENTIFIER) { + CPrep_Error(107); + negativeif(1); + return; + } + + macrocheck = 1; + goendofline(); + if (ismacroname3()) + positiveif(); + else + negativeif(1); +} + +static void prepifndef() { + if (iflevel > 0) { + switch (ifstack[iflevel - 1].state) { + case IfState_1: + case IfState_3: + case IfState_4: + skipendofline(); + negativeif(0); + return; + } + } + + macrocheck = 0; + if (!notendofline()) { + CPrep_Error(112); + negativeif(1); + return; + } + + if (lexidentifier() != TK_IDENTIFIER) { + CPrep_Error(107); + negativeif(1); + return; + } + + macrocheck = 1; + goendofline(); + if (!ismacroname3()) + positiveif(); + else + negativeif(1); +} + +static void prepelif() { + if (iflevel <= 0 || ifstack[iflevel - 1].state == IfState_2 || ifstack[iflevel - 1].state == IfState_4) { + CPrep_Error(118); + skipendofline(); + return; + } + + switch (ifstack[iflevel - 1].state) { + case IfState_1: + doevalconstexpr(); + if (!CInt64_IsZero(&tkintconst)) + ifstack[iflevel - 1].state = IfState_0; + break; + case IfState_3: + skipendofline(); + break; + case IfState_0: + ifstack[iflevel - 1].state = IfState_3; + skipendofline(); + prepifskip(); + break; + default: +#line 5700 + CError_FATAL(); + } +} + +static void prepelse() { + if (iflevel <= 0 || ifstack[iflevel - 1].state == IfState_2 || ifstack[iflevel - 1].state == IfState_4) { + CPrep_Error(118); + skipendofline(); + return; + } + + if (!copts.ANSI_strict) + skipendofline(); + else + goendofline(); + + switch (ifstack[iflevel - 1].state) { + case IfState_1: + ifstack[iflevel - 1].state = IfState_2; + break; + case IfState_0: + ifstack[iflevel - 1].state = IfState_4; + prepifskip(); + break; + case IfState_3: + ifstack[iflevel - 1].state = IfState_4; + break; + default: +#line 5738 + CError_FATAL(); + } +} + +static void prependif() { + if (iflevel <= 0) { + CPrep_Error(118); + skipendofline(); + return; + } + + macrocheck = 0; + if (!copts.ANSI_strict) + skipendofline(); + else + goendofline(); + + macrocheck = 1; + popifstate(); +} + +static void prepifskip() { + // this function does something very weird with its code generation that i can't match + TStreamElement ts; + short t; + + while (iflevel > 0) { + switch (ifstack[iflevel - 1].state) { + case IfState_1: + case IfState_3: + case IfState_4: + restart: + t = prepskipnextchar(); + pos = nextcharpos; + switch (t) { + case 0: + if (tokenstacklevel > 0) { + poptokenseq(); + } else if (tokenstacklevel > 0 || pos >= prep_file_end) { + if (filesp > 0) { + popfile(); + } else { + was_prep_error = 0; + ts.tokenfile = ifstack[iflevel - 1].file; + ts.tokenoffset = ifstack[iflevel - 1].pos; + CError_SetErrorToken(&ts); + CError_ErrorTerm(119); + iflevel = 0; + return; + } + } else { + CPrep_Error(105); + } + goto restart; + case '\r': + newline(); + goto restart; + case '"': + skipendoflinematch(pos, '"'); + goto restart; + case '\'': + skipendoflinematch(pos, '"'); + goto restart; + case '#': + t = prepskipnextchar(); + pos = nextcharpos; + switch (t) { + case '\r': + goto restart; + case 0: + CPrep_Error(102); + default: + pos = ReadIdentifier(pos - 1); + if (!strcmp("if", tkidentifier->name)) { + prepif(); + } else if (!strcmp("ifdef", tkidentifier->name)) { + prepifdef(); + } else if (!strcmp("ifndef", tkidentifier->name)) { + prepifndef(); + } else if (!strcmp("elif", tkidentifier->name)) { + prepelif(); + } else if (!strcmp("else", tkidentifier->name)) { + prepelse(); + } else if (!strcmp("endif", tkidentifier->name)) { + prependif(); + } else { + skipendofline(); + goto restart; + } + } + break; + default: + skipendofline(); + goto restart; + } + default: + return; + } + return; + } +} + +void preprocessor() { + short t; + + gDirectiveStart = pos - prep_file_start; + t = prepskipnextchar(); + pos = nextcharpos; + + switch (t) { + case 0: + CPrep_Error(102); + case '\r': + return; + } + + pos = ReadIdentifier(pos - 1); + if (!strcmp("define", tkidentifier->name)) { + CPrep_Define(); + macrocheck = 1; + return; + } + if (!strcmp("undef", tkidentifier->name)) { + prepundefine(); + macrocheck = 1; + return; + } + if (!strcmp("include", tkidentifier->name)) { + prepinclude(0); + macrocheck = 1; + return; + } + if (!strcmp("line", tkidentifier->name)) { + prepline(); + macrocheck = 1; + return; + } + if (!strcmp("error", tkidentifier->name)) { + CPrep_Error(318); + CError_ResetErrorSkip(); + skipendofline(); + macrocheck = 1; + return; + } + if (!strcmp("pragma", tkidentifier->name)) { + preppragma(); + macrocheck = 1; + return; + } + if (!copts.ANSI_strict) { + if (!strcmp("warning", tkidentifier->name)) { + CPrep_Warning(337); + skipendofline(); + macrocheck = 1; + return; + } + if (!strcmp(tkidentifier->name, "ident")) { + skipendofline(); + macrocheck = 1; + return; + } + } + if (!strcmp("if", tkidentifier->name)) { + macrocheck = 1; + prepif(); + return; + } + if (!strcmp("ifdef", tkidentifier->name)) { + macrocheck = 1; + prepifdef(); + return; + } + if (!strcmp("ifndef", tkidentifier->name)) { + macrocheck = 1; + prepifndef(); + return; + } + if (!strcmp("elif", tkidentifier->name)) { + macrocheck = 1; + prepelif(); + return; + } + if (!strcmp("else", tkidentifier->name)) { + macrocheck = 1; + prepelse(); + return; + } + if (!strcmp("endif", tkidentifier->name)) { + macrocheck = 1; + prependif(); + return; + } + if (copts.objective_c || !copts.ANSI_strict) { + if (!strcmp("import", tkidentifier->name)) { + prepinclude(1); + macrocheck = 1; + return; + } + } + CPrep_Error(104); + skipendofline(); + macrocheck = 1; +} + +SInt32 CPrep_BrowserTokenOffset(FileOffsetInfo *foi) { + return foi->tokenoffset; +} + +SInt32 CPrep_BrowserFileOffset() { + if (ts_first < ts_current) + return ts_current[-1].tokenoffset + 1; + else if (tokenstacklevel) + return tokenstack[0].pos - filestack[filesp]->textbuffer; + else + return pos - filestack[filesp]->textbuffer; +} void CPrep_BrowserFilePosition(CPrepFileInfo **fileinfo, SInt32 *offset) { CPrepFileInfo *file; diff --git a/compiler_and_linker/FrontEnd/C/CPrepTokenizer.c b/compiler_and_linker/FrontEnd/C/CPrepTokenizer.c index 5b77268..62753f8 100644 --- a/compiler_and_linker/FrontEnd/C/CPrepTokenizer.c +++ b/compiler_and_linker/FrontEnd/C/CPrepTokenizer.c @@ -1,156 +1,1889 @@ #include "compiler.h" #include "compiler/tokens.h" +#include "compiler/CError.h" +#include "compiler/CInt64.h" +#include "cos.h" static Boolean prepnextstringchar_foundnl; +#define UCD (unsigned char *) +#define CD (char *) + short prepskipnextchar() { + short c; + unsigned char *start; + unsigned char *p; + + start = UCD pos; + p = UCD pos; +loop: + switch ((c = *p)) { + case 0: + if (tokenstacklevel > 0 || CD p >= prep_file_end) { + pos = CD p; + nextcharpos = CD p; + return c; + } else { + pos = CD p++; + nextcharpos = CD p; + return c; + } + case 4: + case 5: + p++; + goto loop; + case ' ': + case '\t': + case '\n': + case '\v': + case '\f': + spaceskip = 1; + p++; + goto loop; + case ';': + pos = CD p++; + if (tokenstacklevel <= 0 && in_assembler && copts.asmsemicolcomment) { + spaceskip = 1; + nextcharpos = CPrep_SkipNewComment(CD p); + return CPrep_SkipNewCommentChar; + } + nextcharpos = CD p; + return c; + case '#': + pos = CD p++; + if (tokenstacklevel <= 0 && in_assembler && copts.asmpoundcomment) { + spaceskip = 1; + nextcharpos = CPrep_SkipNewComment(CD p); + return CPrep_SkipNewCommentChar; + } + nextcharpos = CD p; + return c; + case '/': + pos = CD p++; + if (copts.multibyteaware) { + while (p[0] == '\\' && !COS_IsMultiByte(CD start, CD p) && p[1] == '\r') { + foundnl(); + if (p[2] == '\n') + p += 3; + else + p += 2; + } + } else { + while (p[0] == '\\' && p[1] == '\r') { + foundnl(); + if (p[2] == '\n') + p += 3; + else + p += 2; + } + } + if (tokenstacklevel <= 0) { + if (p[0] == '/' && (!copts.ANSI_strict || copts.cplusplus || copts.c9x)) { + spaceskip = 1; + nextcharpos = CPrep_SkipNewComment(CD p + 1); + return CPrep_SkipNewCommentChar; + } else if (p[0] == '*') { + spaceskip = 1; + p++; + for (;;) { + if (!(c = *(p++))) { + if (tokenstacklevel > 0 || CD p >= prep_file_end) { + CPrep_Error(103); + nextcharpos = CD p - 1; + return c; + } + p[-1] = ' '; + } + if (c == '*') { + if (copts.multibyteaware) { + while (p[0] == '\\' && !COS_IsMultiByte(CD start, CD p) && p[1] == '\r') { + foundnl(); + if (p[2] == '\n') + p += 3; + else + p += 2; + } + } else { + while (p[0] == '\\' && p[1] == '\r') { + foundnl(); + if (p[2] == '\n') + p += 3; + else + p += 2; + } + } + if (*p == '/') { + p++; + goto loop; + } + } + if (c == '\r') + foundnl(); + } + } + } + nextcharpos = CD p; + return c; + case '%': + pos = CD p++; + if (*p == ':' && copts.cplusplus) { + nextcharpos = CD p + 1; + return '#'; + } + nextcharpos = CD p; + return c; + case '\\': + pos = CD p++; + mid_backslash: + if (*p == '\r') { + if (!copts.multibyteaware || !COS_IsMultiByte(CD start, CD p - 1)) { + foundnl(); + if (p[1] == '\n') + p += 2; + else + p += 1; + goto loop; + } + } + nextcharpos = CD p; + return c; + case '?': + pos = CD p++; + if (copts.trigraphs && p[0] == '?') { + switch (p[1]) { + case '=': + nextcharpos = CD p + 2; + return '#'; + case '/': + c = '\\'; + p += 2; + goto mid_backslash; + case '\'': + nextcharpos = CD p + 2; + return '^'; + case '(': + nextcharpos = CD p + 2; + return '['; + case ')': + nextcharpos = CD p + 2; + return ']'; + case '!': + nextcharpos = CD p + 2; + return '|'; + case '<': + nextcharpos = CD p + 2; + return '{'; + case '>': + nextcharpos = CD p + 2; + return '}'; + case '-': + nextcharpos = CD p + 2; + return '~'; + } + } + nextcharpos = CD p; + return c; + default: + pos = CD p++; + nextcharpos = CD p; + return c; + } } short prepnextchar() { + short c; + unsigned char *start; + unsigned char *p; + + start = UCD pos; + p = UCD pos; +loop: + switch ((c = *(p++))) { + case 0: + pos = CD p - 1; + return c; + case '/': + if (copts.multibyteaware) { + while (p[0] == '\\' && !COS_IsMultiByte(CD start, CD p) && p[1] == '\r') { + foundnl(); + if (p[2] == '\n') + p += 3; + else + p += 2; + } + } else { + while (p[0] == '\\' && p[1] == '\r') { + foundnl(); + if (p[2] == '\n') + p += 3; + else + p += 2; + } + } + if (p[0] == '/' && (!copts.ANSI_strict || copts.cplusplus)) { + spaceskip = 1; + pos = CPrep_SkipNewComment(CD p + 1); + return CPrep_SkipNewCommentChar; + } else if (p[0] == '*') { + spaceskip = 1; + p++; + for (;;) { + if (!(c = *(p++))) { + if (tokenstacklevel > 0 || CD p >= prep_file_end) { + pos = CD p - 1; + CPrep_Error(103); + return c; + } + p[-1] = ' '; + } + if (c == '*') { + if (copts.multibyteaware) { + while (p[0] == '\\' && !COS_IsMultiByte(CD start, CD p) && p[1] == '\r') { + foundnl(); + if (p[2] == '\n') + p += 3; + else + p += 2; + } + } else { + while (p[0] == '\\' && p[1] == '\r') { + foundnl(); + if (p[2] == '\n') + p += 3; + else + p += 2; + } + } + if (*p == '/') + break; + } + if (c == '\r') + foundnl(); + } + pos = CD p + 1; + return ' '; + } else { + pos = CD p; + return c; + } + case '\\': + backslash: + if (*p == '\r') { + if (!copts.multibyteaware || !COS_IsMultiByte(CD start, CD p - 1)) { + foundnl(); + if (p[1] == '\n') + p += 2; + else + p += 1; + goto loop; + } + } + pos = CD p; + return c; + case '%': + if (*p == ':' && copts.cplusplus) { + pos = CD p + 1; + return '#'; + } + pos = CD p; + return c; + case '?': + if (copts.trigraphs && p[0] == '?') { + switch (p[1]) { + case '=': + pos = CD p + 2; + return '#'; + case '/': + c = '\\'; + p += 2; + goto backslash; + case '\'': + pos = CD p + 2; + return '^'; + case '(': + pos = CD p + 2; + return '['; + case ')': + pos = CD p + 2; + return ']'; + case '!': + pos = CD p + 2; + return '|'; + case '<': + pos = CD p + 2; + return '{'; + case '>': + pos = CD p + 2; + return '}'; + case '-': + pos = CD p + 2; + return '~'; + } + } + pos = CD p; + return c; + default: + pos = CD p; + return c; + } } short prepnextstringchar(char *str, Boolean flag) { + unsigned char *p; + short c; + p = UCD pos; + +loop: + switch ((c = *(p++))) { + case 0: + pos = CD p - 1; + return c; + case '\\': + backslash: + if (p[0] == '\r' && (!copts.multibyteaware || !COS_IsMultiByte(str, CD p - 1))) { + if (flag) + foundnl(); + else + prepnextstringchar_foundnl = 1; + if (p[1] == '\n') + p += 2; + else + p += 1; + goto loop; + } + pos = CD p; + return c; + case '?': + if (copts.trigraphs && p[0] == '?') { + switch (p[1]) { + case '=': + pos = CD p + 2; + return '#'; + case '/': + c = '\\'; + p += 2; + goto backslash; + case '\'': + pos = CD p + 2; + return '^'; + case '(': + pos = CD p + 2; + return '['; + case ')': + pos = CD p + 2; + return ']'; + case '!': + pos = CD p + 2; + return '|'; + case '<': + pos = CD p + 2; + return '{'; + case '>': + pos = CD p + 2; + return '}'; + case '-': + pos = CD p + 2; + return '~'; + } + } + pos = CD p; + return c; + default: + pos = CD p; + return c; + } } void CPrep_MatchChar(char ch, Boolean flag) { + char *p; + char *start; + char c; + Boolean r26; + + p = start = pos; + r26 = 0; +loop: + if (!(c = *(p++))) { + if (tokenstacklevel > 0 || p >= prep_file_end) + CPrep_Error(102); + else if (ch == '"') + CPrep_Error(101); + else if (ch == '\'') + CPrep_Error(100); + CPrep_Error(117); + pos = p - 1; + return; + } + + if (c == '\r') { + if (!copts.multibyteaware || !COS_IsMultiByte(start, p - 1)) { + if (flag) + foundnl(); + if (*p == '\n') + p++; + CPrep_Error(112); + pos = p; + return; + } + r26 = 0; + goto loop; + } + + if (c == '?' && p[0] == '?' && copts.trigraphs) { + switch (p[1]) { + case '!': + case '\'': + case '(': + case ')': + case '-': + case '<': + case '=': + case '>': + r26 = 0; + p += 2; + goto loop; + case '/': + p += 2; + goto backslash; + } + } + + if (c == '\\' && !r26 && (!copts.multibyteaware || !COS_IsMultiByte(start, p - 1))) { + backslash: + if (*p == '\r') { + if (flag) + foundnl(); + if (*(++p) == '\n') + p++; + r26 = 0; + } else { + r26 = 1; + } + goto loop; + } + + if (c == ch && !r26) { + pos = p; + } else { + r26 = 0; + goto loop; + } } -char *CPrep_MatchChar2(char *str, char ch, Boolean flag) { +char *CPrep_MatchChar2(char *start, char ch, Boolean flag) { + char *p; + char c; + Boolean r28; + + p = start; + r28 = 0; +loop: + if (!(c = *(p++))) { + if (tokenstacklevel > 0 || p >= prep_file_end) + CPrep_Error(102); + else if (ch == '"') + CPrep_Error(101); + else if (ch == '\'') + CPrep_Error(100); + CPrep_Error(117); + return p - 1; + } + + if (c == '\r') { + if (!copts.multibyteaware || !COS_IsMultiByte(start, p - 1)) { + if (flag) + foundnl(); + if (*p == '\n') + p++; + CPrep_Error(112); + return p; + } + r28 = 0; + goto loop; + } + + if (c == '?' && p[0] == '?' && copts.trigraphs) { + switch (p[1]) { + case '!': + case '\'': + case '(': + case ')': + case '-': + case '<': + case '=': + case '>': + r28 = 0; + p += 2; + goto loop; + case '/': + p += 2; + goto backslash; + } + } + + if (c == '\\' && !r28 && (!copts.multibyteaware || !COS_IsMultiByte(start, p - 1))) { + backslash: + if (*p == '\r') { + if (flag) + foundnl(); + if (*(++p) == '\n') + p++; + r28 = 0; + } else { + r28 = 1; + } + goto loop; + } + + if (c == ch && !r28) { + return p; + } else { + r28 = 0; + goto loop; + } } short prepcurchar() { + char *save_pos; + short t; + + save_pos = pos; + t = prepnextchar(); + nextcharpos = pos; + pos = save_pos; + return t; } static short prepcurstringchar(char *str) { + char *save_pos; + short t; + + save_pos = pos; + prepnextstringchar_foundnl = 0; + t = prepnextstringchar(str, 0); + nextcharpos = pos; + pos = save_pos; + + return t; } static void prepcurstringchar_skip() { + pos = nextcharpos; + if (prepnextstringchar_foundnl) + foundnl(); } -char *ReadIdentifier(char *str) { +char *ReadIdentifier(char *p) { + char buf[256]; + char *start; + int len; + + start = p; + len = 0; +loop: + for (;;) { + if (!cprep_idarray[(unsigned char) *p]) + break; + if (len < 255) + buf[len++] = *p; + p++; + } + + if (copts.multibyteaware) { + if ((unsigned char) *p == '\\' && !COS_IsMultiByte(start, p) && p[1] == '\r') { + if (p[2] == '\n') + p += 3; + else + p += 2; + foundnl(); + goto loop; + } + } else { + if ((unsigned char) *p == '\\' && p[1] == '\r') { + if (p[2] == '\n') + p += 3; + else + p += 2; + foundnl(); + goto loop; + } + } + + buf[len] = 0; + tkidentifier = GetHashNameNodeExport(buf); + return p; } static short intsuffix(short token, Boolean flag) { + Boolean is_unsigned; + Boolean is_long; + Boolean is_longlong; + short t; + + is_unsigned = is_long = is_longlong = 0; + t = token; + switch (t) { + case 'u': + case 'U': + is_unsigned = 1; + pos = nextcharpos; + t = prepcurchar(); + if (t == 'l' || t == 'L') { + is_long = 1; + pos = nextcharpos; + t = *pos; + if (copts.longlong) { + pos = nextcharpos; + t = prepcurchar(); + if (t == 'l' || t == 'L') { + is_longlong = 1; + pos = nextcharpos; + t = *pos; + } + } + } + break; + case 'l': + case 'L': + is_long = 1; + pos = nextcharpos; + t = prepcurchar(); + if (t == 'u' || t == 'U') { + is_unsigned = 1; + pos = nextcharpos; + t = *pos; + } else if (copts.longlong && (t == 'l' || t == 'L')) { + is_longlong = 1; + pos = nextcharpos; + t = prepcurchar(); + if (t == 'u' || t == 'U') { + is_unsigned = 1; + pos = nextcharpos; + t = *pos; + } + } + break; + case 'i': + case 'I': + if (copts.cpp_extensions && !copts.ANSI_strict && copts.longlong) { + pos = nextcharpos; + t = prepcurchar(); + if (t == '6') { + pos = nextcharpos; + t = prepcurchar(); + if (t == '4') { + is_long = is_longlong = 1; + pos = nextcharpos; + t = *pos; + } + } + } + break; + case 'b': + case 'B': + case 'f': + case 'F': + if (InlineAsm_gccmode) + return IT_INT; + break; + } + + if ((t >= 'a' && t <= 'z') || (t >= 'A' && t <= 'Z') || (t == '_') || (t >= '0' && t <= '9')) + CPrep_Error(105); + + if (!is_longlong && !is_long) { + if (!is_unsigned && CInt64_IsInRange(tkintconst, stsignedint.size)) + return IT_INT; + if ((flag || is_unsigned) && CInt64_IsInURange(tkintconst, stunsignedint.size)) + return IT_UINT; + } + if (!is_longlong) { + if (!is_unsigned && CInt64_IsInRange(tkintconst, stsignedlong.size)) + return IT_LONG; + if (CInt64_IsInURange(tkintconst, stunsignedlong.size)) + return IT_ULONG; + } + if (copts.longlong) { + if (!is_unsigned && CInt64_IsInRange(tkintconst, stsignedlonglong.size)) + return IT_LONGLONG; + if (CInt64_IsInURange(tkintconst, stsignedlonglong.size)) + return IT_ULONGLONG; + } + CError_Error(154); + tkintconst = cint64_zero; + return IT_INT; } static short floatsuffix(short token) { + short whichtype; + + switch (token) { + case 'f': + case 'F': + pos = nextcharpos; + token = *pos; + whichtype = IT_FLOAT; + if (stfloat.size != stlongdouble.size) + tkfloatconst = CMach_CalcFloatConvert((Type *) &stfloat, tkfloatconst); + break; + case 'l': + case 'L': + pos = nextcharpos; + token = *pos; + whichtype = IT_LONGDOUBLE; + break; + case 'd': + case 'D': + if (!copts.ANSI_strict) { + pos = nextcharpos; + token = *pos; + whichtype = IT_DOUBLE; + if (stdouble.size != stlongdouble.size) + tkfloatconst = CMach_CalcFloatConvert((Type *) &stdouble, tkfloatconst); + } + break; + default: + if (copts.float_constants) { + whichtype = IT_FLOAT; + if (stfloat.size != stlongdouble.size) + tkfloatconst = CMach_CalcFloatConvert((Type *) &stfloat, tkfloatconst); + } else { + whichtype = IT_DOUBLE; + if (stdouble.size != stlongdouble.size) + tkfloatconst = CMach_CalcFloatConvert((Type *) &stdouble, tkfloatconst); + } + } + + if ((token >= 'a' && token <= 'z') || (token >= 'A' && token <= 'Z') || (token == '_') || (token >= '0' && token <= '9')) { + CPrep_Error(105); + whichtype = IT_DOUBLE; + } + + return whichtype; } static short tohex(short token) { + if (token >= '0' && token <= '9') + return token - '0'; + if (token >= 'a' && token <= 'f') + return token - 'a' + 10; + if (token >= 'A' && token <= 'F') + return token - 'A' + 10; + return -1; } -static short nextchar(char *str) { +static SInt32 nextchar(char *str) { + // minor register allocation issues + SInt32 chr_max; + short tmpchr; + SInt32 chr; + Boolean out_of_bounds; + short i; + short t; + + chr_max = 0xFF; + if (widestring) chr_max = 0xFFFF; + + was_escchar = 0; + t = prepnextstringchar(str, 1); + + if (t == '\\' && (!copts.multibyteaware || !COS_IsMultiByte(str, pos - 1))) { + was_escchar = 1; + t = prepnextstringchar(str, 1); + switch (t) { + case 'a': return 7; + case 'b': return 8; + case 't': return 9; + case 'v': return 11; + case 'f': return 12; + case 'n': + if (copts.mpwc_newline) + return 13; + else + return 10; + case 'r': + if (copts.mpwc_newline) + return 10; + else + return 13; + case 'e': return 27; + case 'x': + chr = tohex(prepnextstringchar(str, 1)); + if (chr == -1) { + CPrep_Error(100); + return ' '; + } + out_of_bounds = 0; + while (tohex(tmpchr = prepcurstringchar(str)) != -1) { + chr = (chr << 4) + tohex(tmpchr); + prepcurstringchar_skip(); + if (chr & ~chr_max) + out_of_bounds = 1; + } + if (out_of_bounds) + CError_Error(100); + break; + default: + if (t >= '0' && t <= '7') { + out_of_bounds = 0; + i = 1; + chr = t - '0'; + while (i < 3 && (tmpchr = prepcurstringchar(str)) >= '0' && tmpchr <= '9') { + chr = (chr << 3) + (tmpchr - '0'); + prepcurstringchar_skip(); + if (chr & ~chr_max) + out_of_bounds = 1; + i++; + } + if (out_of_bounds) + CError_Error(100); + } else { + chr = t; + } + } + } else { + chr = t; + } + + if (chr_max == 0xFF) + return (char) (chr & chr_max); + else + return (chr & chr_max); } char *CPrep_SkipNewComment(char *str) { - } -Boolean skipendoflinematch(char *str, Boolean flag) { +Boolean skipendoflinematch(char *str, short token) { } void skipendofline() { } void CPrep_SkipAsmComment() { + Boolean save_macrocheck = macrocheck; + skipendofline(); + macrocheck = save_macrocheck; +} + +static short tille() { return TK_NEG6; } + +static short tcret() { + newline(); + if (cprep_eoltokens) + return TK_NEG7; + else + return 0; +} + +static short tapos() { + // has register allocation issues + UInt32 maxvalue; + int bytecount; + CInt64 ci58; + CInt64 ci50; + CInt64 ci48; + SInt32 t; + SInt32 t2; + int i; + char *start; + + start = pos; + t = nextchar(pos); + if ((t == '\'' || t == 0 || t == '\r') && !was_escchar) { + CPrep_Error(100); + tkintconst = cint64_zero; + tksize = IT_INT; + return TK_INTCONST; + } + + t2 = nextchar(start); + if (t2 == '\'' && !was_escchar) { + if (widestring) { + switch (stwchar.size) { + case 1: + CInt64_SetULong(&tkintconst, (UInt8) t); + tksize = copts.cplusplus ? IT_SCHAR : IT_INT; + break; + case 2: + CInt64_SetULong(&tkintconst, (UInt16) t); + tksize = IT_UINT; + break; + case 4: + CInt64_SetULong(&tkintconst, (UInt32) t); + tksize = IT_UINT; + break; + default: +#line 1386 + CError_FATAL(); + } + } else { + if (copts.unsignedchars) + t &= 0xFF; + CInt64_SetLong(&tkintconst, t); + tksize = copts.cplusplus ? IT_SCHAR : IT_INT; + } + } else { + if (widestring) { + switch (stwchar.size) { + case 1: + CInt64_SetULong(&ci50, 8); + maxvalue = 0xFF; + bytecount = 1; + break; + case 2: + CInt64_SetULong(&ci50, 16); + maxvalue = 0xFFFF; + bytecount = 2; + break; + case 4: + CInt64_SetULong(&ci50, 32); + maxvalue = 0xFFFFFFFF; + bytecount = 4; + break; + default: +#line 1424 + CError_FATAL(); + } + } else { + CInt64_SetULong(&ci50, 8); + maxvalue = 0xFF; + bytecount = 1; + } + + CInt64_SetULong(&tkintconst, t & maxvalue); + i = bytecount; + do { + if ((t2 == 0 || t2 == '\r') && !was_escchar) { + CPrep_Error(100); + goto after_char_const; + } + CInt64_SetULong(&ci48, t2 & maxvalue); + ci58 = CInt64_Shl(tkintconst, ci50); + tkintconst = CInt64_Or(ci58, ci48); + i += bytecount; + t2 = nextchar(start); + if (t2 == '\'' && !was_escchar) + goto after_char_const; + } while (i < stunsignedlonglong.size); + CPrep_Error(100); + after_char_const: + if (i <= stunsignedint.size && i < stunsignedlong.size) + tksize = IT_UINT; + else if (i <= stunsignedlong.size) + tksize = IT_ULONG; + else + tksize = IT_ULONGLONG; + } + + return TK_INTCONST; +} + +static short tquot() { + // has register allocation issues + TypeIntegral *type; // r22 + char *string_ptr; // r21 + SInt32 r20; // r20 + char *save_pos; // r19 + short c; // r19 + char *start_pos; // r18 + CInt64 ch64; + + start_pos = pos; + at_linestart = 0; + if (cprep_nostring) + return '"'; + + string_ptr = *stringmem; + ispascalstring = 0; + r20 = 0; + if (widestring) + type = &stwchar; + else + type = &stchar; + + if (prepcurstringchar(start_pos) == '\\') { + save_pos = pos; + prepcurstringchar_skip(); + if (prepcurstringchar(start_pos) == 'p') { + prepcurstringchar_skip(); + ispascalstring = 1; + string_ptr += type->size; + } else { + pos = save_pos; + } + } + + do { + c = nextchar(start_pos); + if ((c == '"' || c == '\r' || c == 0) && !was_escchar) { + if (c == 0 && (tokenstacklevel > 0 || pos >= prep_file_end)) + CPrep_Error(102); + else if (c != '"') + CPrep_Error(101); + break; + } + if ((r20 + type->size) >= maxstringsize) { + string_ptr = (char *) (string_ptr - *stringmem); + if (!COS_ResizeHandle(stringmem, maxstringsize += 256)) + CError_NoMem(); + string_ptr = *stringmem + (SInt32) string_ptr; + } + if (type->size != 1) { + CInt64_SetLong(&ch64, c); + CMach_InitIntMem((Type *) type, ch64, string_ptr); + string_ptr += type->size; + r20 += type->size; + } else { + *string_ptr = c; + string_ptr++; + r20++; + } + } while (1); + + if (ispascalstring) { + if (r20 > 255 && type->size == 1) { + CPrep_Error(106); + r20 = 255; + } + CInt64_SetLong(&ch64, r20 / type->size); + CMach_InitIntMem((Type *) type, ch64, *stringmem); + r20 += type->size; + } else { + if ((r20 + 1) >= maxstringsize) { + if (!COS_ResizeHandle(stringmem, maxstringsize += 256)) + CError_NoMem(); + CMach_InitIntMem((Type *) type, cint64_zero, *stringmem + r20); + r20 += type->size; + } + } + + tksize = r20; + tkstring = galloc(r20); + memcpy(tkstring, *stringmem, tksize); + if (widestring) + return TK_STRING_WIDE; + else + return TK_STRING; +} + +static short thash() { + if (at_linestart) { + preprocessor(); + return 0; + } + return '#'; +} + +static short tmult() { + at_linestart = 0; + if (prepcurchar() == '=') { + pos = nextcharpos; + return TK_MULT_ASSIGN; + } + return '*'; +} + +static short tcolo() { + char t2; + at_linestart = 0; + if (copts.cplusplus) { + t2 = prepcurchar(); + if (t2 == ':') { + pos = nextcharpos; + return TK_COLON_COLON; + } + if (t2 == '>' && !preprocessing_only) { + pos = nextcharpos; + return ']'; + } + } + return ':'; +} + +static short tless() { + short t2; + at_linestart = 0; + t2 = prepcurchar(); + if (t2 == '=') { + pos = nextcharpos; + return TK_LESS_EQUAL; + } + if (t2 == '<') { + pos = nextcharpos; + if (prepcurchar() == '=') { + pos = nextcharpos; + return TK_SHL_ASSIGN; + } else { + return TK_SHL; + } + } + if (t2 == '%' && copts.cplusplus && !preprocessing_only) { + pos = nextcharpos; + return '{'; + } + if (t2 == ':' && copts.cplusplus && !preprocessing_only) { + pos = nextcharpos; + return '['; + } + return '<'; +} + +static short tequa(short) { + at_linestart = 0; + if (prepcurchar() == '=') { + pos = nextcharpos; + return TK_LOGICAL_EQ; + } + return '='; +} + +static short tgrea(short) { + short t2; + at_linestart = 0; + t2 = prepcurchar(); + if (t2 == '=') { + pos = nextcharpos; + return TK_GREATER_EQUAL; + } + if (t2 == '>') { + pos = nextcharpos; + if (prepcurchar() == '=') { + pos = nextcharpos; + return TK_SHR_ASSIGN; + } else { + return TK_SHR; + } + } + return '>'; +} + +static short tatsg(short) { + char *start_pos; + Boolean save_idarray; + + start_pos = pos; + at_linestart = 0; + + if (copts.objective_c || in_assembler) { + save_idarray = cprep_idarray['@']; + cprep_idarray['@'] = 1; + pos = ReadIdentifier(start_pos - 1); + cprep_idarray['@'] = save_idarray; + + if (copts.objective_c) { + if (!strcmp("@interface", tkidentifier->name)) + return TK_AT_INTERFACE; + if (!strcmp("@implementation", tkidentifier->name)) + return TK_AT_IMPLEMENTATION; + if (!strcmp("@protocol", tkidentifier->name)) + return TK_AT_PROTOCOL; + if (!strcmp("@end", tkidentifier->name)) + return TK_AT_END; + if (!strcmp("@private", tkidentifier->name)) + return TK_AT_PRIVATE; + if (!strcmp("@protected", tkidentifier->name)) + return TK_AT_PROTECTED; + if (!strcmp("@public", tkidentifier->name)) + return TK_AT_PUBLIC; + if (!strcmp("@class", tkidentifier->name)) + return TK_AT_CLASS; + if (!strcmp("@selector", tkidentifier->name)) + return TK_AT_SELECTOR; + if (!strcmp("@encode", tkidentifier->name)) + return TK_AT_ENCODE; + if (!strcmp("@defs", tkidentifier->name)) + return TK_AT_DEFS; + } + + if (in_assembler) + return TK_IDENTIFIER; + + pos = start_pos; + } + + return '@'; +} + +static short tperc(short) { + char t2; + at_linestart = 0; + t2 = prepcurchar(); + if (t2 == '=') { + pos = nextcharpos; + return TK_MOD_ASSIGN; + } + if (t2 == '>' && copts.cplusplus && !preprocessing_only) { + pos = nextcharpos; + return '}'; + } + return '%'; +} + +static short texcl() { + at_linestart = 0; + if (prepcurchar() == '=') { + pos = nextcharpos; + return TK_LOGICAL_NE; + } + return '!'; +} + +static short tplus() { + short t2; + at_linestart = 0; + t2 = prepcurchar(); + if (t2 == '=') { + pos = nextcharpos; + return TK_ADD_ASSIGN; + } + if (t2 == '+') { + pos = nextcharpos; + return TK_INCREMENT; + } + return '+'; +} + +static short tminu() { + short t2; + at_linestart = 0; + t2 = prepcurchar(); + if (t2 == '=') { + pos = nextcharpos; + return TK_SUB_ASSIGN; + } + if (t2 == '-') { + pos = nextcharpos; + return TK_DECREMENT; + } + if (t2 == '>') { + pos = nextcharpos; + if (copts.cplusplus && prepcurchar() == '*') { + pos = nextcharpos; + return TK_ARROW_STAR; + } + return TK_ARROW; + } + return '-'; +} + +static short torrr() { + short t2; + at_linestart = 0; + t2 = prepcurchar(); + if (t2 == '=') { + pos = nextcharpos; + return TK_OR_ASSIGN; + } + if (t2 == '|') { + pos = nextcharpos; + return TK_LOGICAL_OR; + } + return '|'; +} + +static short tampe() { + short t2; + at_linestart = 0; + t2 = prepcurchar(); + if (t2 == '=') { + pos = nextcharpos; + return TK_AND_ASSIGN; + } + if (t2 == '&') { + pos = nextcharpos; + return TK_LOGICAL_AND; + } + return '&'; +} + +static short tpowe() { + at_linestart = 0; + if (prepcurchar() == '=') { + pos = nextcharpos; + return TK_XOR_ASSIGN; + } + return '^'; +} + +static short tdivi() { + at_linestart = 0; + if (prepcurchar() == '=') { + pos = nextcharpos; + return TK_DIV_ASSIGN; + } + return '/'; } -static short tille() {} -static short tcret() {} -static short tapos() {} -static short tquot() {} -static short thash() {} -static short tmult() {} -static short tcolo() {} -static short tless() {} -static short tequa() {} -static short tgrea() {} -static short tatsg() {} -static short tperc() {} -static short texcl() {} -static short tplus() {} -static short tminu() {} -static short torrr() {} -static short tampe() {} -static short tpowe() {} -static short tdivi() {} static short tzero() {} static short tpoin() {} static short tnumb() {} -static short tiden() {} + +static short tiden() { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + else + return TK_IDENTIFIER; +} + static short tchrL() {} -static short tchra() {} -static short tchrb() {} -static short tchrc() {} -static short tchrd() {} -static short tchre() {} -static short tchrf() {} -static short tchrg() {} -static short tchri() {} -static short tchrl() {} -static short tchrm() {} -static short tchrn() {} -static short tchro() {} -static short tchrp() {} -static short tchrr() {} -static short tchrs() {} -static short tchrt() {} -static short tchru() {} -static short tchrv() {} -static short tchrw() {} -static short tchrx() {} -static short tchr_() {} -static short token() {} -static short tdoll() {} -static short tisid() {} -static short tnull() {} -static short t0x1a() {} - -static short (*cprep_tokenize[256])() = { - &tnull, &tille, &tille, &tille, &tisid, &tisid, &tille, &tille, - &tille, &tille, &tille, &tille, &tille, &tcret, &tille, &tille, - &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, - &tille, &tille, &t0x1a, &tille, &tille, &tille, &tille, &tille, - &tille, &texcl, &tquot, &thash, &tdoll, &tperc, &tampe, &tapos, - &token, &token, &tmult, &tplus, &token, &tminu, &tpoin, &tdivi, - &tzero, &tnumb, &tnumb, &tnumb, &tnumb, &tnumb, &tnumb, &tnumb, - &tnumb, &tnumb, &tcolo, &token, &tless, &tequa, &tgrea, &token, - &tatsg, &tiden, &tiden, &tiden, &tiden, &tiden, &tiden, &tiden, - &tiden, &tiden, &tiden, &tiden, &tchrL, &tiden, &tchrn, &tiden, - &tchrp, &tiden, &tiden, &tiden, &tiden, &tiden, &tiden, &tiden, - &tchrx, &tiden, &tiden, &token, &token, &token, &tpowe, &tchr_, - &token, &tchra, &tchrb, &tchrc, &tchrd, &tchre, &tchrf, &tchrg, - &tiden, &tchri, &tiden, &tiden, &tchrl, &tchrm, &tchrn, &tchro, - &tchrp, &tiden, &tchrr, &tchrs, &tchrt, &tchru, &tchrv, &tchrw, - &tchrx, &tiden, &tiden, &token, &torrr, &token, &token, &tille, - &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, - &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, - &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, - &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, - &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, - &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, - &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, - &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, - &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, - &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, - &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, - &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, - &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, - &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, - &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille, - &tille, &tille, &tille, &tille, &tille, &tille, &tille, &tille + +static short tchra() { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + if (!strcmp("auto", tkidentifier->name)) + return TK_AUTO; + if ((copts.cplusplus || !copts.only_std_keywords) && !strcmp("asm", tkidentifier->name)) + return TK_ASM; + if (copts.cplusplus && !in_assembler && !preprocessing_only) { + if (!strcmp("and", tkidentifier->name)) + return TK_LOGICAL_AND; + if (!strcmp("and_eq", tkidentifier->name)) + return TK_AND_ASSIGN; + } + return TK_IDENTIFIER; +} + +static short tchrb() { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + if (!strcmp("break", tkidentifier->name)) + return TK_BREAK; + if (copts.cplusplus) { + if (copts.booltruefalse && !strcmp("bool", tkidentifier->name)) + return TK_BOOL; + if (!in_assembler && !preprocessing_only) { + if (!strcmp("bitand", tkidentifier->name)) + return '&'; + if (!strcmp("bitor", tkidentifier->name)) + return '|'; + } + } + if (copts.objective_c) { + if (!strcmp("bycopy", tkidentifier->name)) + return TK_BYCOPY; + if (!strcmp("byref", tkidentifier->name)) + return TK_BYREF; + } + return TK_IDENTIFIER; +} + +static short tchrc() { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + if (!strcmp("case", tkidentifier->name)) + return TK_CASE; + if (!strcmp("char", tkidentifier->name)) + return TK_CHAR; + if (!strcmp("const", tkidentifier->name)) + return TK_CONST; + if (!strcmp("continue", tkidentifier->name)) + return TK_CONTINUE; + if (copts.cplusplus) { + if (!strcmp("const_cast", tkidentifier->name)) { + if (copts.ecplusplus) + CPrep_Warning(339); + return TK_CONST_CAST; + } + if (!strcmp("catch", tkidentifier->name)) { + if (copts.ecplusplus) + CPrep_Warning(339); + return TK_CATCH; + } + if (!strcmp("class", tkidentifier->name)) + return TK_CLASS; + if (!in_assembler && !preprocessing_only) { + if (!strcmp("compl", tkidentifier->name)) + return '~'; + } + } + return TK_IDENTIFIER; +} + +static short tchrd() { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + if (!strcmp("default", tkidentifier->name)) + return TK_DEFAULT; + if (!strcmp("do", tkidentifier->name)) + return TK_DO; + if (!strcmp("double", tkidentifier->name)) + return TK_DOUBLE; + if (copts.cplusplus) { + if (!strcmp("delete", tkidentifier->name)) + return TK_DELETE; + if (!strcmp("dynamic_cast", tkidentifier->name)) { + if (copts.ecplusplus) + CPrep_Warning(339); + return TK_DYNAMIC_CAST; + } + } + return TK_IDENTIFIER; +} + +static short tchre() { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + if (!strcmp("else", tkidentifier->name)) + return TK_ELSE; + if (!strcmp("enum", tkidentifier->name)) + return TK_ENUM; + if (!strcmp("extern", tkidentifier->name)) + return TK_EXTERN; + if (copts.cplusplus) { + if (!strcmp("explicit", tkidentifier->name)) + return TK_EXPLICIT; + if (!strcmp("export", tkidentifier->name) && !copts.ecplusplus) + return TK_EXPORT; + } + return TK_IDENTIFIER; +} + +static short tchrf() { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + if (!strcmp("float", tkidentifier->name)) + return TK_FLOAT; + if (!strcmp("for", tkidentifier->name)) + return TK_FOR; + if (copts.cplusplus) { + if (!strcmp("friend", tkidentifier->name)) + return TK_FRIEND; + if (copts.booltruefalse && !strcmp("false", tkidentifier->name)) + return TK_FALSE; + } + return TK_IDENTIFIER; +} + +static short tchrg() { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + if (!strcmp("goto", tkidentifier->name)) + return TK_GOTO; + return TK_IDENTIFIER; +} + +static short tchri() { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + if (!strcmp("if", tkidentifier->name)) + return TK_IF; + if (!strcmp("int", tkidentifier->name)) + return TK_INT; + if (copts.cplusplus || copts.c9x) { + if (!strcmp("inline", tkidentifier->name)) + return TK_INLINE; + } else if (!copts.only_std_keywords) { + if (!strcmp("inline", tkidentifier->name)) + return TK_INLINE; + } + if (copts.objective_c) { + if (!strcmp("in", tkidentifier->name)) + return TK_IN; + if (!strcmp("inout", tkidentifier->name)) + return TK_INOUT; + } + return TK_IDENTIFIER; +} + +static short tchrl() { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + if (!strcmp("long", tkidentifier->name)) + return TK_LONG; + return TK_IDENTIFIER; +} + +static short tchrm() { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + if (copts.cplusplus && !strcmp("mutable", tkidentifier->name)) { + if (copts.ecplusplus) + CPrep_Warning(339); + return TK_MUTABLE; + } + return TK_IDENTIFIER; +} + +static short tchrn(short t) { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + if (copts.cplusplus && t == 'n') { + if (!strcmp("new", tkidentifier->name)) + return TK_NEW; + if (!strcmp("namespace", tkidentifier->name)) { + if (copts.ecplusplus) + CPrep_Warning(339); + return TK_NAMESPACE; + } + if (!in_assembler && !preprocessing_only) { + if (!strcmp("not", tkidentifier->name)) + return '!'; + if (!strcmp("not_eq", tkidentifier->name)) + return TK_LOGICAL_NE; + } + } + return TK_IDENTIFIER; +} + +static short tchro() { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + if (copts.cplusplus) { + if (!strcmp("operator", tkidentifier->name)) + return TK_OPERATOR; + if (!in_assembler && !preprocessing_only) { + if (!strcmp("or", tkidentifier->name)) + return TK_LOGICAL_OR; + if (!strcmp("or_eq", tkidentifier->name)) + return TK_OR_ASSIGN; + } + } + if (copts.objective_c) { + if (!strcmp("out", tkidentifier->name)) + return TK_OUT; + if (!strcmp("oneway", tkidentifier->name)) + return TK_ONEWAY; + } + return TK_IDENTIFIER; +} + +static short tchrp(short t) { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + if (!copts.only_std_keywords && !strcmp("pascal", tkidentifier->name)) + return TK_PASCAL; + if (copts.cplusplus && t == 'p') { + if (!strcmp("private", tkidentifier->name)) + return TK_PRIVATE; + if (!strcmp("protected", tkidentifier->name)) + return TK_PROTECTED; + if (!strcmp("public", tkidentifier->name)) + return TK_PUBLIC; + } + return TK_IDENTIFIER; +} + +static short tchrr() { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + if (!strcmp("register", tkidentifier->name)) + return TK_REGISTER; + if (!strcmp("return", tkidentifier->name)) + return TK_RETURN; + if (copts.cplusplus && !strcmp("reinterpret_cast", tkidentifier->name)) { + if (copts.ecplusplus) + CPrep_Warning(339); + return TK_REINTERPRET_CAST; + } + if (copts.c9x && !strcmp("restrict", tkidentifier->name)) + return TK_RESTRICT; + return TK_IDENTIFIER; +} + +static short tchrs() { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + if (!strcmp("short", tkidentifier->name)) + return TK_SHORT; + if (!strcmp("signed", tkidentifier->name)) + return TK_SIGNED; + if (!strcmp("sizeof", tkidentifier->name)) + return TK_SIZEOF; + if (!strcmp("static", tkidentifier->name)) + return TK_STATIC; + if (!strcmp("struct", tkidentifier->name)) + return TK_STRUCT; + if (!strcmp("switch", tkidentifier->name)) + return TK_SWITCH; + if (copts.cplusplus && !strcmp("static_cast", tkidentifier->name)) { + if (copts.ecplusplus) + CPrep_Warning(339); + return TK_STATIC_CAST; + } + return TK_IDENTIFIER; +} + +static short tchrt() { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + if (!strcmp("typedef", tkidentifier->name)) + return TK_TYPEDEF; + if (copts.gcc_extensions && !strcmp("typeof", tkidentifier->name)) + return TK_UU_TYPEOF_UU; + if (copts.cplusplus) { + if (!strcmp("this", tkidentifier->name)) + return TK_THIS; + if (copts.booltruefalse && !strcmp("true", tkidentifier->name)) + return TK_TRUE; + if (!strcmp("template", tkidentifier->name)) { + if (copts.ecplusplus) + CPrep_Warning(339); + return TK_TEMPLATE; + } + if (!strcmp("try", tkidentifier->name)) { + if (copts.ecplusplus) + CPrep_Warning(339); + return TK_TRY; + } + if (!strcmp("throw", tkidentifier->name)) { + if (copts.ecplusplus) + CPrep_Warning(339); + return TK_THROW; + } + if (!strcmp("typeid", tkidentifier->name)) { + if (copts.ecplusplus) + CPrep_Warning(339); + return TK_TYPEID; + } + if (!strcmp("typename", tkidentifier->name)) { + if (copts.ecplusplus) + CPrep_Warning(339); + return TK_TYPENAME; + } + } + return TK_IDENTIFIER; +} + +static short tchru() { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + if (!strcmp("union", tkidentifier->name)) + return TK_UNION; + if (!strcmp("unsigned", tkidentifier->name)) + return TK_UNSIGNED; + if (copts.cplusplus && !strcmp("using", tkidentifier->name)) { + if (copts.ecplusplus) + CPrep_Warning(339); + return TK_USING; + } + return TK_IDENTIFIER; +} + +static short tchrv() { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + if (!strcmp("void", tkidentifier->name)) + return TK_VOID; + if (!strcmp("volatile", tkidentifier->name)) + return TK_VOLATILE; + if (copts.cplusplus && !strcmp("virtual", tkidentifier->name)) + return TK_VIRTUAL; + return TK_IDENTIFIER; +} + +static short tchrw() { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + if (!strcmp("while", tkidentifier->name)) + return TK_WHILE; + if (copts.cplusplus && copts.wchar_type && !strcmp("wchar_t", tkidentifier->name)) + return TK_WCHAR_T; + return TK_IDENTIFIER; +} + +static short tchrx(short t) { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + + if (copts.cplusplus && t == 'x' && !in_assembler && !preprocessing_only) { + if (!strcmp("xor", tkidentifier->name)) + return '^'; + if (!strcmp("xor_eq", tkidentifier->name)) + return TK_XOR_ASSIGN; + } + + return TK_IDENTIFIER; +} + +static short tchr_() { + at_linestart = 0; + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + + if (!strcmp("__stdcall", tkidentifier->name)) + return TK_UU_STDCALL; + if (!strcmp("__cdecl", tkidentifier->name)) + return TK_UU_CDECL; + if (!strcmp("__fastcall", tkidentifier->name)) + return TK_UU_FASTCALL; + if (!strcmp("__declspec", tkidentifier->name)) + return TK_UU_DECLSPEC; + if (!strcmp("__asm", tkidentifier->name)) + return TK_ASM; + if (!strcmp("__asm__", tkidentifier->name)) + return TK_ASM; + if (!strcmp("__inline", tkidentifier->name)) + return TK_INLINE; + if (!strcmp("__inline__", tkidentifier->name)) + return TK_INLINE; + if (!strcmp("__restrict", tkidentifier->name)) + return TK_RESTRICT; + if (!strcmp("__restrict__", tkidentifier->name)) + return TK_RESTRICT; + if (!strcmp("__attribute__", tkidentifier->name)) + return TK_UU_ATTRIBUTE_UU; + if (!strcmp("__far", tkidentifier->name)) + return TK_UU_FAR; + if (!strcmp("__alignof__", tkidentifier->name)) + return TK_UU_ALIGNOF_UU; + if (!strcmp("__typeof__", tkidentifier->name)) + return TK_UU_TYPEOF_UU; + if (copts.c9x) { + if (!strcmp("_Bool", tkidentifier->name)) + return TK_BOOL; + if (!strcmp("_Complex", tkidentifier->name)) + return TK_U_COMPLEX; + if (!strcmp("_Imaginary", tkidentifier->name)) + return TK_U_IMAGINARY; + } + if (copts.altivec_model && !strcmp("__vector", tkidentifier->name)) + return TK_UU_VECTOR; + return TK_IDENTIFIER; +} + +static short token(short t) { + at_linestart = 0; + return t; +} + +static short tdoll(short t) { + at_linestart = 0; + return t; +} + +static short tisid() { + if (!tokenstacklevel) + CError_Error(105); + return 0; +} + +static short tnull(short t) { + if (tokenstacklevel > 0 || pos >= prep_file_end) { + at_linestart = 0; + return t; + } else { + pos[-1] = -64; + return TK_NEG6; + } +} + +static short t0x1a() { + if (*pos == 0) + return 0; + else + return TK_NEG6; +} + +typedef short (*TokenizePtr)(short); +#define F(func) ((TokenizePtr) (&func)) + +static TokenizePtr cprep_tokenize[256] = { + F(tnull), F(tille), F(tille), F(tille), F(tisid), F(tisid), F(tille), F(tille), + F(tille), F(tille), F(tille), F(tille), F(tille), F(tcret), F(tille), F(tille), + F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), + F(tille), F(tille), F(t0x1a), F(tille), F(tille), F(tille), F(tille), F(tille), + F(tille), F(texcl), F(tquot), F(thash), F(tdoll), F(tperc), F(tampe), F(tapos), + F(token), F(token), F(tmult), F(tplus), F(token), F(tminu), F(tpoin), F(tdivi), + F(tzero), F(tnumb), F(tnumb), F(tnumb), F(tnumb), F(tnumb), F(tnumb), F(tnumb), + F(tnumb), F(tnumb), F(tcolo), F(token), F(tless), F(tequa), F(tgrea), F(token), + F(tatsg), F(tiden), F(tiden), F(tiden), F(tiden), F(tiden), F(tiden), F(tiden), + F(tiden), F(tiden), F(tiden), F(tiden), F(tchrL), F(tiden), F(tchrn), F(tiden), + F(tchrp), F(tiden), F(tiden), F(tiden), F(tiden), F(tiden), F(tiden), F(tiden), + F(tchrx), F(tiden), F(tiden), F(token), F(token), F(token), F(tpowe), F(tchr_), + F(token), F(tchra), F(tchrb), F(tchrc), F(tchrd), F(tchre), F(tchrf), F(tchrg), + F(tiden), F(tchri), F(tiden), F(tiden), F(tchrl), F(tchrm), F(tchrn), F(tchro), + F(tchrp), F(tiden), F(tchrr), F(tchrs), F(tchrt), F(tchru), F(tchrv), F(tchrw), + F(tchrx), F(tiden), F(tiden), F(token), F(torrr), F(token), F(token), F(tille), + F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), + F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), + F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), + F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), + F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), + F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), + F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), + F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), + F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), + F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), + F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), + F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), + F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), + F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), + F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), + F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille) }; short lookahead() { + SInt32 state; + short t; + + CPrep_TokenStreamGetState(&state); + t = lex(); + CPrep_TokenStreamSetState(&state); + + return t; } short lookahead_noeol() { + SInt32 state; + short t; + + CPrep_TokenStreamGetState(&state); + do { + t = lex(); + } while (t == TK_NEG7); + CPrep_TokenStreamSetState(&state); + + return t; } static void CPrep_StringConCat(Boolean flag) { @@ -160,7 +1893,45 @@ short lex() { } short plex() { + // does not match - global refs in wrong order + short t; + + while (1) { + t = prepskipnextchar(); + pos = nextcharpos; + if ((t = cprep_tokenize[t](t))) + return t; + + if (!*pos) { + if (tokenstacklevel > 0) { + poptokenseq(); + } else if (filesp > 0) { + popfile(); + } else { + break; + } + } + } + + return 0; } short lexidentifier() { + short t; + char *save_pos; + + t = prepskipnextchar(); + pos = nextcharpos; + at_linestart = 0; + if ((t >= 'a' && t <= 'z') || (t >= 'A' && t <= 'Z') || (t == '_')) { + pos = ReadIdentifier(pos - 1); + return TK_IDENTIFIER; + } else if (t == '.') { + save_pos = pos; + if (prepnextchar() == '.' && prepnextchar() == '.') + return TK_ELLIPSIS; + else + pos = save_pos; + } + return t; } diff --git a/compiler_and_linker/FrontEnd/C/CScope.c b/compiler_and_linker/FrontEnd/C/CScope.c index 7423c07..06cbd6c 100644 --- a/compiler_and_linker/FrontEnd/C/CScope.c +++ b/compiler_and_linker/FrontEnd/C/CScope.c @@ -1,5 +1,9 @@ #include "compiler.h" #include "compiler/CError.h" +#include "compiler/CMangler.h" +#include "compiler/CParser.h" +#include "compiler/CPrep.h" +#include "compiler/CScope.h" #include "compiler/enode.h" #include "compiler/objects.h" #include "compiler/scopes.h" @@ -1016,7 +1020,7 @@ static NameSpaceObjectList *CScope_FindLookupName(NameSpaceLookupList *list, Has if (r6->object->otype == r30->object->otype) { switch (r6->object->otype) { case OT_TYPE: - if ((OBJ_TYPE(r6->object)->type == OBJ_TYPE(r30->object)->type) && (OBJ_TYPE(r6->object)->unk6 == OBJ_TYPE(r30->object)->unk6)) + if ((OBJ_TYPE(r6->object)->type == OBJ_TYPE(r30->object)->type) && (OBJ_TYPE(r6->object)->qual == OBJ_TYPE(r30->object)->qual)) goto break1; break; case OT_TYPETAG: @@ -1196,7 +1200,7 @@ static Boolean CScope_SetupParseNameResult(CScopeParseResult *result, NameSpaceO return 0; case OT_TYPE: result->x8 = OBJ_TYPE(list->object)->type; - result->xC = OBJ_TYPE(list->object)->unk6; + result->xC = OBJ_TYPE(list->object)->qual; result->obj_10 = list->object; result->name_4 = name; result->x20 = 1; @@ -1388,7 +1392,7 @@ inline Boolean CScope_NSIteratorNext(CScopeNSIterator *iterator) { } } -Type *CScope_GetType(NameSpace *nspace, HashNameNode *name, void **unk6) { +Type *CScope_GetType(NameSpace *nspace, HashNameNode *name, UInt32 *qual) { CScopeParseResult result; CScopeNSIterator iterator; NameSpaceObjectList *list; @@ -1400,13 +1404,13 @@ Type *CScope_GetType(NameSpace *nspace, HashNameNode *name, void **unk6) { do { for (list = CScope_NSIteratorFind(&iterator, name); list; list = list->next) { if (list->object->otype == OT_TYPETAG) { - if (unk6) - *unk6 = NULL; + if (qual) + *qual = 0; return OBJ_TYPE_TAG(list->object)->type; } if (list->object->otype == OT_TYPE) { - if (unk6) - *unk6 = OBJ_TYPE(list->object)->unk6; + if (qual) + *qual = OBJ_TYPE(list->object)->qual; return OBJ_TYPE(list->object)->type; } } @@ -2429,7 +2433,7 @@ static void CScope_AddUsingObject(BClassList *bcl, NameSpace *nspace, ObjBase *o if (!nspace->theclass) { if ((list = CScope_FindQualName(nspace, name)) && (list->object->otype == OT_TYPE) && (OBJ_TYPE(obj)->type == OBJ_TYPE(list->object)->type) && - (OBJ_TYPE(obj)->unk6 == OBJ_TYPE(list->object)->unk6)) + (OBJ_TYPE(obj)->qual == OBJ_TYPE(list->object)->qual)) return; } copy = galloc(sizeof(ObjType)); @@ -2530,7 +2534,7 @@ void CScope_AddClassUsingDeclaration(TypeClass *tclass, TypeClass *tclass2, Hash } } -void CScope_ParseUsingDeclaration(NameSpace *nspace, AccessType access) { +void CScope_ParseUsingDeclaration(NameSpace *nspace, short access, Boolean flag) { // almost matches, slight bit of register weirdness CScopeParseResult result; |