diff options
author | Ash Wolf <ninji@wuffs.org> | 2023-01-10 11:05:21 +0000 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2023-01-10 11:05:21 +0000 |
commit | aec1b8dddc68ecb8288ec6132932e4c7b4bca09f (patch) | |
tree | 8138328fe43bcc5fff690dc60caac79aa570ab2b | |
parent | fcfbafff31869ed808bff0639532db1828660e92 (diff) | |
download | MWCC-aec1b8dddc68ecb8288ec6132932e4c7b4bca09f.tar.gz MWCC-aec1b8dddc68ecb8288ec6132932e4c7b4bca09f.zip |
getting close to done
80 files changed, 21184 insertions, 3213 deletions
diff --git a/compiler_and_linker/FrontEnd/C/CPrep.c b/compiler_and_linker/FrontEnd/C/CPrep.c index 4b66e88..f38c504 100644 --- a/compiler_and_linker/FrontEnd/C/CPrep.c +++ b/compiler_and_linker/FrontEnd/C/CPrep.c @@ -281,7 +281,7 @@ static Boolean dofreeaheap; static GList mlist; static Handle ts_buffer; static TStreamElement *ts_first; -static TStreamElement *ts_last; +TStreamElement *ts_last; TStreamElement *ts_current; static SInt32 ts_elements; SInt32 ts_preread_elements; diff --git a/compiler_and_linker/FrontEnd/C/CPrepTokenizer.c b/compiler_and_linker/FrontEnd/C/CPrepTokenizer.c index 62753f8..4ea0fb0 100644 --- a/compiler_and_linker/FrontEnd/C/CPrepTokenizer.c +++ b/compiler_and_linker/FrontEnd/C/CPrepTokenizer.c @@ -1,32 +1,34 @@ -#include "compiler.h" -#include "compiler/tokens.h" +#include "compiler/CPrepTokenizer.h" #include "compiler/CError.h" #include "compiler/CInt64.h" +#include "compiler/CMachine.h" +#include "compiler/CParser.h" +#include "compiler/CPrep.h" +#include "compiler/CompilerTools.h" +#include "compiler/InlineAsmPPC.h" +#include "compiler/tokens.h" #include "cos.h" static Boolean prepnextstringchar_foundnl; -#define UCD (unsigned char *) -#define CD (char *) - -short prepskipnextchar() { +short prepskipnextchar(void) { short c; - unsigned char *start; - unsigned char *p; + StringPtr start; + StringPtr p; - start = UCD pos; - p = UCD pos; + start = (StringPtr) pos; + p = (StringPtr) pos; loop: switch ((c = *p)) { case 0: - if (tokenstacklevel > 0 || CD p >= prep_file_end) { - pos = CD p; - nextcharpos = CD p; + if (tokenstacklevel > 0 || p >= (StringPtr) prep_file_end) { + pos = (char *) p; + nextcharpos = (char *) p; return c; } else { - pos = CD p++; - nextcharpos = CD p; + pos = (char *) p++; + nextcharpos = (char *) p; return c; } case 4: @@ -42,27 +44,27 @@ loop: p++; goto loop; case ';': - pos = CD p++; + pos = (char *) p++; if (tokenstacklevel <= 0 && in_assembler && copts.asmsemicolcomment) { spaceskip = 1; - nextcharpos = CPrep_SkipNewComment(CD p); + nextcharpos = (char *) CPrep_SkipNewComment(p); return CPrep_SkipNewCommentChar; } - nextcharpos = CD p; + nextcharpos = (char *) p; return c; case '#': - pos = CD p++; + pos = (char *) p++; if (tokenstacklevel <= 0 && in_assembler && copts.asmpoundcomment) { spaceskip = 1; - nextcharpos = CPrep_SkipNewComment(CD p); + nextcharpos = (char *) CPrep_SkipNewComment(p); return CPrep_SkipNewCommentChar; } - nextcharpos = CD p; + nextcharpos = (char *) p; return c; case '/': - pos = CD p++; + pos = (char *) p++; if (copts.multibyteaware) { - while (p[0] == '\\' && !COS_IsMultiByte(CD start, CD p) && p[1] == '\r') { + while (p[0] == '\\' && !COS_IsMultiByte(start, p) && p[1] == '\r') { foundnl(); if (p[2] == '\n') p += 3; @@ -81,23 +83,23 @@ loop: if (tokenstacklevel <= 0) { if (p[0] == '/' && (!copts.ANSI_strict || copts.cplusplus || copts.c9x)) { spaceskip = 1; - nextcharpos = CPrep_SkipNewComment(CD p + 1); + nextcharpos = (char *) CPrep_SkipNewComment(p + 1); return CPrep_SkipNewCommentChar; } else if (p[0] == '*') { spaceskip = 1; p++; for (;;) { if (!(c = *(p++))) { - if (tokenstacklevel > 0 || CD p >= prep_file_end) { + if (tokenstacklevel > 0 || p >= (StringPtr) prep_file_end) { CPrep_Error(103); - nextcharpos = CD p - 1; + nextcharpos = (char *) p - 1; return c; } p[-1] = ' '; } if (c == '*') { if (copts.multibyteaware) { - while (p[0] == '\\' && !COS_IsMultiByte(CD start, CD p) && p[1] == '\r') { + while (p[0] == '\\' && !COS_IsMultiByte(start, p) && p[1] == '\r') { foundnl(); if (p[2] == '\n') p += 3; @@ -123,21 +125,21 @@ loop: } } } - nextcharpos = CD p; + nextcharpos = (char *) p; return c; case '%': - pos = CD p++; + pos = (char *) p++; if (*p == ':' && copts.cplusplus) { - nextcharpos = CD p + 1; + nextcharpos = (char *) p + 1; return '#'; } - nextcharpos = CD p; + nextcharpos = (char *) p; return c; case '\\': - pos = CD p++; + pos = (char *) p++; mid_backslash: if (*p == '\r') { - if (!copts.multibyteaware || !COS_IsMultiByte(CD start, CD p - 1)) { + if (!copts.multibyteaware || !COS_IsMultiByte(start, p - 1)) { foundnl(); if (p[1] == '\n') p += 2; @@ -146,67 +148,67 @@ loop: goto loop; } } - nextcharpos = CD p; + nextcharpos = (char *) p; return c; case '?': - pos = CD p++; + pos = (char *) p++; if (copts.trigraphs && p[0] == '?') { switch (p[1]) { case '=': - nextcharpos = CD p + 2; + nextcharpos = (char *) p + 2; return '#'; case '/': c = '\\'; p += 2; goto mid_backslash; case '\'': - nextcharpos = CD p + 2; + nextcharpos = (char *) p + 2; return '^'; case '(': - nextcharpos = CD p + 2; + nextcharpos = (char *) p + 2; return '['; case ')': - nextcharpos = CD p + 2; + nextcharpos = (char *) p + 2; return ']'; case '!': - nextcharpos = CD p + 2; + nextcharpos = (char *) p + 2; return '|'; case '<': - nextcharpos = CD p + 2; + nextcharpos = (char *) p + 2; return '{'; case '>': - nextcharpos = CD p + 2; + nextcharpos = (char *) p + 2; return '}'; case '-': - nextcharpos = CD p + 2; + nextcharpos = (char *) p + 2; return '~'; } } - nextcharpos = CD p; + nextcharpos = (char *) p; return c; default: - pos = CD p++; - nextcharpos = CD p; + pos = (char *) p++; + nextcharpos = (char *) p; return c; } } -short prepnextchar() { +short prepnextchar(void) { short c; - unsigned char *start; - unsigned char *p; + StringPtr start; + StringPtr p; - start = UCD pos; - p = UCD pos; + start = (StringPtr) pos; + p = (StringPtr) pos; loop: switch ((c = *(p++))) { case 0: - pos = CD p - 1; + pos = (char *) p - 1; return c; case '/': if (copts.multibyteaware) { - while (p[0] == '\\' && !COS_IsMultiByte(CD start, CD p) && p[1] == '\r') { + while (p[0] == '\\' && !COS_IsMultiByte(start, p) && p[1] == '\r') { foundnl(); if (p[2] == '\n') p += 3; @@ -224,15 +226,15 @@ loop: } if (p[0] == '/' && (!copts.ANSI_strict || copts.cplusplus)) { spaceskip = 1; - pos = CPrep_SkipNewComment(CD p + 1); + pos = (char *) CPrep_SkipNewComment(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; + if (tokenstacklevel > 0 || p >= (StringPtr) prep_file_end) { + pos = (char *) p - 1; CPrep_Error(103); return c; } @@ -240,7 +242,7 @@ loop: } if (c == '*') { if (copts.multibyteaware) { - while (p[0] == '\\' && !COS_IsMultiByte(CD start, CD p) && p[1] == '\r') { + while (p[0] == '\\' && !COS_IsMultiByte(start, p) && p[1] == '\r') { foundnl(); if (p[2] == '\n') p += 3; @@ -262,16 +264,16 @@ loop: if (c == '\r') foundnl(); } - pos = CD p + 1; + pos = (char *) p + 1; return ' '; } else { - pos = CD p; + pos = (char *) p; return c; } case '\\': backslash: if (*p == '\r') { - if (!copts.multibyteaware || !COS_IsMultiByte(CD start, CD p - 1)) { + if (!copts.multibyteaware || !COS_IsMultiByte(start, p - 1)) { foundnl(); if (p[1] == '\n') p += 2; @@ -280,70 +282,70 @@ loop: goto loop; } } - pos = CD p; + pos = (char *) p; return c; case '%': if (*p == ':' && copts.cplusplus) { - pos = CD p + 1; + pos = (char *) p + 1; return '#'; } - pos = CD p; + pos = (char *) p; return c; case '?': if (copts.trigraphs && p[0] == '?') { switch (p[1]) { case '=': - pos = CD p + 2; + pos = (char *) p + 2; return '#'; case '/': c = '\\'; p += 2; goto backslash; case '\'': - pos = CD p + 2; + pos = (char *) p + 2; return '^'; case '(': - pos = CD p + 2; + pos = (char *) p + 2; return '['; case ')': - pos = CD p + 2; + pos = (char *) p + 2; return ']'; case '!': - pos = CD p + 2; + pos = (char *) p + 2; return '|'; case '<': - pos = CD p + 2; + pos = (char *) p + 2; return '{'; case '>': - pos = CD p + 2; + pos = (char *) p + 2; return '}'; case '-': - pos = CD p + 2; + pos = (char *) p + 2; return '~'; } } - pos = CD p; + pos = (char *) p; return c; default: - pos = CD p; + pos = (char *) p; return c; } } -short prepnextstringchar(char *str, Boolean flag) { - unsigned char *p; +short prepnextstringchar(StringPtr str, Boolean flag) { + StringPtr p; short c; - p = UCD pos; + p = (StringPtr) pos; loop: switch ((c = *(p++))) { case 0: - pos = CD p - 1; + pos = (char *) p - 1; return c; case '\\': backslash: - if (p[0] == '\r' && (!copts.multibyteaware || !COS_IsMultiByte(str, CD p - 1))) { + if (p[0] == '\r' && (!copts.multibyteaware || !COS_IsMultiByte(str, p - 1))) { if (flag) foundnl(); else @@ -354,45 +356,45 @@ loop: p += 1; goto loop; } - pos = CD p; + pos = (char *) p; return c; case '?': if (copts.trigraphs && p[0] == '?') { switch (p[1]) { case '=': - pos = CD p + 2; + pos = (char *) p + 2; return '#'; case '/': c = '\\'; p += 2; goto backslash; case '\'': - pos = CD p + 2; + pos = (char *) p + 2; return '^'; case '(': - pos = CD p + 2; + pos = (char *) p + 2; return '['; case ')': - pos = CD p + 2; + pos = (char *) p + 2; return ']'; case '!': - pos = CD p + 2; + pos = (char *) p + 2; return '|'; case '<': - pos = CD p + 2; + pos = (char *) p + 2; return '{'; case '>': - pos = CD p + 2; + pos = (char *) p + 2; return '}'; case '-': - pos = CD p + 2; + pos = (char *) p + 2; return '~'; } } - pos = CD p; + pos = (char *) p; return c; default: - pos = CD p; + pos = (char *) p; return c; } } @@ -401,10 +403,10 @@ void CPrep_MatchChar(char ch, Boolean flag) { char *p; char *start; char c; - Boolean r26; + Boolean haveBackslash; p = start = pos; - r26 = 0; + haveBackslash = 0; loop: if (!(c = *(p++))) { @@ -429,7 +431,7 @@ loop: pos = p; return; } - r26 = 0; + haveBackslash = 0; goto loop; } @@ -443,7 +445,7 @@ loop: case '<': case '=': case '>': - r26 = 0; + haveBackslash = 0; p += 2; goto loop; case '/': @@ -452,24 +454,24 @@ loop: } } - if (c == '\\' && !r26 && (!copts.multibyteaware || !COS_IsMultiByte(start, p - 1))) { + if (c == '\\' && !haveBackslash && (!copts.multibyteaware || !COS_IsMultiByte(start, p - 1))) { backslash: if (*p == '\r') { if (flag) foundnl(); if (*(++p) == '\n') p++; - r26 = 0; + haveBackslash = 0; } else { - r26 = 1; + haveBackslash = 1; } goto loop; } - if (c == ch && !r26) { + if (c == ch && !haveBackslash) { pos = p; } else { - r26 = 0; + haveBackslash = 0; goto loop; } } @@ -477,10 +479,10 @@ loop: char *CPrep_MatchChar2(char *start, char ch, Boolean flag) { char *p; char c; - Boolean r28; + Boolean haveBackslash; p = start; - r28 = 0; + haveBackslash = 0; loop: if (!(c = *(p++))) { @@ -503,7 +505,7 @@ loop: CPrep_Error(112); return p; } - r28 = 0; + haveBackslash = 0; goto loop; } @@ -517,7 +519,7 @@ loop: case '<': case '=': case '>': - r28 = 0; + haveBackslash = 0; p += 2; goto loop; case '/': @@ -526,29 +528,29 @@ loop: } } - if (c == '\\' && !r28 && (!copts.multibyteaware || !COS_IsMultiByte(start, p - 1))) { + if (c == '\\' && !haveBackslash && (!copts.multibyteaware || !COS_IsMultiByte(start, p - 1))) { backslash: if (*p == '\r') { if (flag) foundnl(); if (*(++p) == '\n') p++; - r28 = 0; + haveBackslash = 0; } else { - r28 = 1; + haveBackslash = 1; } goto loop; } - if (c == ch && !r28) { + if (c == ch && !haveBackslash) { return p; } else { - r28 = 0; + haveBackslash = 0; goto loop; } } -short prepcurchar() { +short prepcurchar(void) { char *save_pos; short t; @@ -560,7 +562,7 @@ short prepcurchar() { return t; } -static short prepcurstringchar(char *str) { +static short prepcurstringchar(StringPtr str) { char *save_pos; short t; @@ -573,51 +575,54 @@ static short prepcurstringchar(char *str) { return t; } -static void prepcurstringchar_skip() { +static void prepcurstringchar_skip(void) { pos = nextcharpos; if (prepnextstringchar_foundnl) foundnl(); } -char *ReadIdentifier(char *p) { +char *ReadIdentifier(const char *p) { char buf[256]; - char *start; + const char *start; + unsigned int ch; 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; + ch = (unsigned char) *p; + if (cprep_idarray[ch]) { + if (len < 255) + buf[len++] = *p; + p++; + } else { + if (copts.multibyteaware) { + if ((unsigned char) *p == '\\' && !COS_IsMultiByte(start, p) && p[1] == '\r') { + if (p[2] == '\n') + p += 3; + else + p += 2; + foundnl(); + } else { + break; + } + } else { + if ((unsigned char) *p == '\\' && p[1] == '\r') { + if (p[2] == '\n') + p += 3; + else + p += 2; + foundnl(); + } else { + break; + } + } } } buf[len] = 0; tkidentifier = GetHashNameNodeExport(buf); - return p; + return (char *) p; } static short intsuffix(short token, Boolean flag) { @@ -778,12 +783,11 @@ static short tohex(short token) { return -1; } -static SInt32 nextchar(char *str) { - // minor register allocation issues - SInt32 chr_max; +static SInt32 nextchar(StringPtr str) { short tmpchr; - SInt32 chr; + SInt32 chr_max; Boolean out_of_bounds; + SInt32 chr; short i; short t; @@ -795,8 +799,7 @@ static SInt32 nextchar(char *str) { if (t == '\\' && (!copts.multibyteaware || !COS_IsMultiByte(str, pos - 1))) { was_escchar = 1; - t = prepnextstringchar(str, 1); - switch (t) { + switch ((t = prepnextstringchar(str, 1))) { case 'a': return 7; case 'b': return 8; case 't': return 9; @@ -820,7 +823,7 @@ static SInt32 nextchar(char *str) { return ' '; } out_of_bounds = 0; - while (tohex(tmpchr = prepcurstringchar(str)) != -1) { + while (tohex((tmpchr = prepcurstringchar(str))) != -1) { chr = (chr << 4) + tohex(tmpchr); prepcurstringchar_skip(); if (chr & ~chr_max) @@ -834,8 +837,8 @@ static SInt32 nextchar(char *str) { out_of_bounds = 0; i = 1; chr = t - '0'; - while (i < 3 && (tmpchr = prepcurstringchar(str)) >= '0' && tmpchr <= '9') { - chr = (chr << 3) + (tmpchr - '0'); + while (i < 3 && (tmpchr = prepcurstringchar(str)) >= '0' && tmpchr <= '7') { + chr = (chr << 3) + tmpchr - '0'; prepcurstringchar_skip(); if (chr & ~chr_max) out_of_bounds = 1; @@ -857,24 +860,233 @@ static SInt32 nextchar(char *str) { return (chr & chr_max); } -char *CPrep_SkipNewComment(char *str) { +StringPtr CPrep_SkipNewComment(StringPtr str) { + StringPtr p; + + p = str; + while (1) { + switch (*(p++)) { + case 0: + if (tokenstacklevel > 0 || p >= (StringPtr) prep_file_end) { + CPrep_SkipNewCommentChar = 0; + return p - 1; + } + p[-1] = ' '; + continue; + + case '\r': + CPrep_SkipNewCommentChar = '\r'; + return p; + + case '\\': + if (copts.multibyteaware && COS_IsMultiByte(str, p - 1)) + continue; + + if (*p == '\r') { + ++p; + foundnl(); + } + + if (*p == '\n') + p++; + continue; + + case '"': + if (InlineAsm_gccmode) { + CPrep_SkipNewCommentChar = '\r'; + return p - 1; + } + continue; + } + } } -Boolean skipendoflinematch(char *str, short token) { +Boolean skipendoflinematch(StringPtr str, short token) { + StringPtr start; + + start = str - 1; + pos = (char *) start; + + while (1) { + switch (*(str++)) { + case 0: + case '\r': + pos = (char *) str - 1; + return 0; + + case '"': + if (token == '"') { + pos = (char *) str; + return 1; + } + break; + + case '\'': + if (token == '\'') { + pos = (char *) str; + return 1; + } + break; + + case '\\': + if (copts.multibyteaware && COS_IsMultiByte(start, str - 1)) + continue; + + switch (*(str++)) { + case 0: + pos = (char *) str - 1; + return 0; + + case '\r': + foundnl(); + if (*str == '\n') + str++; + break; + } + break; + + case '?': + if (copts.trigraphs && str[0] == '?' && str[1] == '/' && str[2] == '\r') { + foundnl(); + str += 3; + } + break; + } + } } -void skipendofline() { +void skipendofline(void) { + StringPtr start; + StringPtr p; + short ch; + + start = (StringPtr) pos; + p = (StringPtr) pos; + + while (1) { + switch (*(p++)) { + case 0: + case '\r': + pos = (char *) p - 1; + return; + + case '"': + if (!skipendoflinematch(p, '"')) + return; + p = (StringPtr) pos; + break; + + case '\'': + if (!skipendoflinematch(p, '\'')) + return; + p = (StringPtr) pos; + break; + + case '/': + if (copts.multibyteaware) { + while (*p == '\\' && !COS_IsMultiByte(start, p) && p[1] == '\r') { + foundnl(); + if (p[2] == '\n') + p += 3; + else + p += 2; + } + } else { + while (*p == '\\' && p[1] == '\r') { + foundnl(); + if (p[2] == '\n') + p += 3; + else + p += 2; + } + } + + if (*p == '/' && (!copts.ANSI_strict || copts.cplusplus)) { + // EOL comment + pos = (char *) CPrep_SkipNewComment(p + 1); + if (CPrep_SkipNewCommentChar == '\r') + pos--; + return; + } + + if (*p == '*') { + // Block comment + pos = (char *) p - 1; + spaceskip = 1; + p++; + while (1) { + if ((ch = *(p++)) == 0) { + if (tokenstacklevel > 0 || p >= (StringPtr) prep_file_end) { + pos = (char *) p - 1; + CPrep_Error(103); + return; + } + p[-1] = ' '; + } + + if (ch == '*') { + if (copts.multibyteaware) { + while (*p == '\\' && !COS_IsMultiByte(start, p) && p[1] == '\r') { + foundnl(); + if (p[2] == '\n') + p += 3; + else + p += 2; + } + } else { + while (*p == '\\' && p[1] == '\r') { + foundnl(); + if (p[2] == '\n') + p += 3; + else + p += 2; + } + } + + if (*p == '/') { + p++; + break; + } + } + + if (ch == '\r') + foundnl(); + } + } + break; + + case '\\': + if (copts.multibyteaware && COS_IsMultiByte(start, p - 1)) + continue; + + if (*p == '\r') { + foundnl(); + if (p[1] == '\n') + p += 2; + else + p += 1; + } + break; + + case '?': + if (copts.trigraphs && p[0] == '?' && p[1] == '/' && p[2] == '\r') { + foundnl(); + p += 3; + } + break; + } + } } -void CPrep_SkipAsmComment() { +void CPrep_SkipAsmComment(void) { Boolean save_macrocheck = macrocheck; skipendofline(); macrocheck = save_macrocheck; } -static short tille() { return TK_NEG6; } +static short tille(void) { return TK_NEG6; } -static short tcret() { +static short tcret(void) { newline(); if (cprep_eoltokens) return TK_NEG7; @@ -882,20 +1094,18 @@ static short tcret() { return 0; } -static short tapos() { - // has register allocation issues +static short tapos(short _t) { + int t; + int t2; + int i; + StringPtr start; UInt32 maxvalue; int bytecount; - CInt64 ci58; - CInt64 ci50; - CInt64 ci48; - SInt32 t; - SInt32 t2; - int i; - char *start; + CInt64 newBits; + CInt64 val; - start = pos; - t = nextchar(pos); + start = (StringPtr) pos; + t = nextchar((StringPtr) pos); if ((t == '\'' || t == 0 || t == '\r') && !was_escchar) { CPrep_Error(100); tkintconst = cint64_zero; @@ -920,8 +1130,7 @@ static short tapos() { tksize = IT_UINT; break; default: -#line 1386 - CError_FATAL(); + CError_FATAL(1386); } } else { if (copts.unsignedchars) @@ -933,48 +1142,53 @@ static short tapos() { if (widestring) { switch (stwchar.size) { case 1: - CInt64_SetULong(&ci50, 8); + CInt64_SetULong(&val, 8); maxvalue = 0xFF; bytecount = 1; break; case 2: - CInt64_SetULong(&ci50, 16); + CInt64_SetULong(&val, 16); maxvalue = 0xFFFF; bytecount = 2; break; case 4: - CInt64_SetULong(&ci50, 32); + CInt64_SetULong(&val, 32); maxvalue = 0xFFFFFFFF; bytecount = 4; break; default: -#line 1424 - CError_FATAL(); + CError_FATAL(1424); } } else { - CInt64_SetULong(&ci50, 8); + CInt64_SetULong(&val, 8); maxvalue = 0xFF; bytecount = 1; } CInt64_SetULong(&tkintconst, t & maxvalue); i = bytecount; - do { + + while (1) { if ((t2 == 0 || t2 == '\r') && !was_escchar) { CPrep_Error(100); - goto after_char_const; + break; } - CInt64_SetULong(&ci48, t2 & maxvalue); - ci58 = CInt64_Shl(tkintconst, ci50); - tkintconst = CInt64_Or(ci58, ci48); + + CInt64_SetULong(&newBits, t2 & maxvalue); + tkintconst = CInt64_Or(CInt64_Shl(tkintconst, val), newBits); 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) + break; + + if (i >= stunsignedlonglong.size) { + CPrep_Error(100); + break; + } + } + + if (i <= stunsignedint.size && stunsignedint.size < stunsignedlong.size) tksize = IT_UINT; else if (i <= stunsignedlong.size) tksize = IT_ULONG; @@ -985,42 +1199,41 @@ static short tapos() { 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 +static short tquot(short t) { + Type *type; + StringPtr string_ptr; + SInt32 size; + short c; + StringPtr save_pos; + StringPtr start_pos; CInt64 ch64; - start_pos = pos; + start_pos = (StringPtr) pos; at_linestart = 0; if (cprep_nostring) return '"'; - string_ptr = *stringmem; + string_ptr = (StringPtr) *stringmem; ispascalstring = 0; - r20 = 0; + size = 0; if (widestring) - type = &stwchar; + type = TYPE(&stwchar); else - type = &stchar; + type = TYPE(&stchar); if (prepcurstringchar(start_pos) == '\\') { - save_pos = pos; + save_pos = (StringPtr) pos; prepcurstringchar_skip(); if (prepcurstringchar(start_pos) == 'p') { prepcurstringchar_skip(); ispascalstring = 1; string_ptr += type->size; } else { - pos = save_pos; + pos = (char *) save_pos; } } - do { + while (1) { c = nextchar(start_pos); if ((c == '"' || c == '\r' || c == 0) && !was_escchar) { if (c == 0 && (tokenstacklevel > 0 || pos >= prep_file_end)) @@ -1029,51 +1242,53 @@ static short tquot() { CPrep_Error(101); break; } - if ((r20 + type->size) >= maxstringsize) { - string_ptr = (char *) (string_ptr - *stringmem); + if ((size + type->size) >= maxstringsize) { + SInt32 offset = string_ptr - (StringPtr) *stringmem; if (!COS_ResizeHandle(stringmem, maxstringsize += 256)) CError_NoMem(); - string_ptr = *stringmem + (SInt32) string_ptr; + string_ptr = (StringPtr) *stringmem + offset; } if (type->size != 1) { CInt64_SetLong(&ch64, c); - CMach_InitIntMem((Type *) type, ch64, string_ptr); + CMach_InitIntMem(type, ch64, string_ptr); string_ptr += type->size; - r20 += type->size; + size += type->size; } else { *string_ptr = c; string_ptr++; - r20++; + size++; } - } while (1); + } if (ispascalstring) { - if (r20 > 255 && type->size == 1) { + if (size > 255 && type->size == 1) { CPrep_Error(106); - r20 = 255; + size = 255; } - CInt64_SetLong(&ch64, r20 / type->size); - CMach_InitIntMem((Type *) type, ch64, *stringmem); - r20 += type->size; + CInt64_SetLong(&ch64, size / type->size); + CMach_InitIntMem(type, ch64, *stringmem); + size += type->size; } else { - if ((r20 + 1) >= maxstringsize) { + if ((size + 1) >= maxstringsize) { if (!COS_ResizeHandle(stringmem, maxstringsize += 256)) CError_NoMem(); - CMach_InitIntMem((Type *) type, cint64_zero, *stringmem + r20); - r20 += type->size; } + CMach_InitIntMem(type, cint64_zero, *stringmem + size); + size += type->size; } - tksize = r20; - tkstring = galloc(r20); + tksize = size; + tkstring = galloc(size); memcpy(tkstring, *stringmem, tksize); + if (widestring) - return TK_STRING_WIDE; + c = TK_STRING_WIDE; else - return TK_STRING; + c = TK_STRING; + return (short) c; } -static short thash() { +static short thash(void) { if (at_linestart) { preprocessor(); return 0; @@ -1081,7 +1296,7 @@ static short thash() { return '#'; } -static short tmult() { +static short tmult(void) { at_linestart = 0; if (prepcurchar() == '=') { pos = nextcharpos; @@ -1090,7 +1305,7 @@ static short tmult() { return '*'; } -static short tcolo() { +static short tcolo(void) { char t2; at_linestart = 0; if (copts.cplusplus) { @@ -1107,7 +1322,7 @@ static short tcolo() { return ':'; } -static short tless() { +static short tless(void) { short t2; at_linestart = 0; t2 = prepcurchar(); @@ -1165,10 +1380,9 @@ static short tgrea(short) { } static short tatsg(short) { - char *start_pos; - Boolean save_idarray; + char save_idarray; + char *start_pos = pos; - start_pos = pos; at_linestart = 0; if (copts.objective_c || in_assembler) { @@ -1226,7 +1440,7 @@ static short tperc(short) { return '%'; } -static short texcl() { +static short texcl(void) { at_linestart = 0; if (prepcurchar() == '=') { pos = nextcharpos; @@ -1235,7 +1449,7 @@ static short texcl() { return '!'; } -static short tplus() { +static short tplus(void) { short t2; at_linestart = 0; t2 = prepcurchar(); @@ -1250,7 +1464,7 @@ static short tplus() { return '+'; } -static short tminu() { +static short tminu(void) { short t2; at_linestart = 0; t2 = prepcurchar(); @@ -1273,7 +1487,7 @@ static short tminu() { return '-'; } -static short torrr() { +static short torrr(void) { short t2; at_linestart = 0; t2 = prepcurchar(); @@ -1288,7 +1502,7 @@ static short torrr() { return '|'; } -static short tampe() { +static short tampe(void) { short t2; at_linestart = 0; t2 = prepcurchar(); @@ -1303,7 +1517,7 @@ static short tampe() { return '&'; } -static short tpowe() { +static short tpowe(void) { at_linestart = 0; if (prepcurchar() == '=') { pos = nextcharpos; @@ -1312,7 +1526,7 @@ static short tpowe() { return '^'; } -static short tdivi() { +static short tdivi(void) { at_linestart = 0; if (prepcurchar() == '=') { pos = nextcharpos; @@ -1321,11 +1535,117 @@ static short tdivi() { return '/'; } -static short tzero() {} -static short tpoin() {} -static short tnumb() {} +// forward decl +static short tnumb(short t); + +static short tzero(short t) { + char *p; + short ch; + Boolean failed; + Boolean floatFailed; + + if (InlineAsm_gccmode && InlineAsm_labelref) + return tnumb(t); + + at_linestart = 0; + + p = pos - 1; + ch = prepnextchar(); + if (ch == 'x' || ch == 'X') { + p = CInt64_ScanHexString(&tkintconst, pos, &failed); + if (pos == p) + CError_Error(CErrorStr105); + pos = p; + } else if (!copts.ANSI_strict && (ch == 'b' || ch == 'B')) { + p = CInt64_ScanBinString(&tkintconst, pos, &failed); + if (pos == p) + CError_Error(CErrorStr105); + pos = p; + } else { + while (ch >= '0' && ch <= '9') + ch = prepnextchar(); + + switch (ch) { + case '.': + case 'E': + case 'e': + pos = CMach_FloatScan(p, &tkfloatconst, &floatFailed); + if (floatFailed) + CPrep_Error(154); + tksize = floatsuffix(prepcurchar()); + return TK_FLOATCONST; + } + + pos = CInt64_ScanOctString(&tkintconst, p, &failed); + } + + if (failed) { + CPrep_Error(154); + tkintconst = cint64_zero; + } + + tksize = intsuffix(prepcurchar(), 1); + return TK_INTCONST; +} + +static short tpoin(void) { + char *p; + short ch; + Boolean failed; + + at_linestart = 0; + + p = pos - 1; + ch = prepnextchar(); + + if (ch >= '0' && ch <= '9') { + pos = CMach_FloatScan(p, &tkfloatconst, &failed); + if (failed) + CPrep_Error(154); + tksize = floatsuffix(prepcurchar()); + return TK_FLOATCONST; + } + + if (copts.cplusplus && ch == '*') + return TK_DOT_STAR; + + if (ch == '.' && prepnextchar() == '.') + return TK_ELLIPSIS; + + pos = p + 1; + return '.'; +} + +static short tnumb(short t) { + char *p; + short ch; + Boolean failed; + Boolean floatFailed; -static short tiden() { + at_linestart = 0; + + p = pos - 1; + pos = CInt64_ScanDecString(&tkintconst, p, &failed); + + ch = prepcurchar(); + if (ch == '.' || ch == 'e' || ch == 'E') { + pos = CMach_FloatScan(p, &tkfloatconst, &floatFailed); + if (floatFailed) + CPrep_Error(154); + tksize = floatsuffix(prepcurchar()); + return TK_FLOATCONST; + } + + if (failed) { + CPrep_Error(154); + tkintconst = cint64_zero; + } + + tksize = intsuffix(prepcurchar(), 0); + return TK_INTCONST; +} + +static short tiden(void) { at_linestart = 0; pos = ReadIdentifier(pos - 1); if (macrocheck && macrotest()) @@ -1334,9 +1654,37 @@ static short tiden() { return TK_IDENTIFIER; } -static short tchrL() {} +static short tchrL(void) { + short ch; + + at_linestart = 0; + + if ((ch = prepcurchar()) == '\'') { + widestring = 1; + pos = nextcharpos; + ch = tapos(ch); + widestring = 0; + + tksize = (copts.wchar_type && copts.cplusplus) ? IT_WCHAR_T : IT_INT; + return ch; + } + + if (ch == '"') { + widestring = 1; + pos = nextcharpos; + ch = tquot(ch); + widestring = 0; + return ch; + } + + pos = ReadIdentifier(pos - 1); + if (macrocheck && macrotest()) + return 0; + + return TK_IDENTIFIER; +} -static short tchra() { +static short tchra(void) { at_linestart = 0; pos = ReadIdentifier(pos - 1); if (macrocheck && macrotest()) @@ -1354,7 +1702,7 @@ static short tchra() { return TK_IDENTIFIER; } -static short tchrb() { +static short tchrb(void) { at_linestart = 0; pos = ReadIdentifier(pos - 1); if (macrocheck && macrotest()) @@ -1380,7 +1728,7 @@ static short tchrb() { return TK_IDENTIFIER; } -static short tchrc() { +static short tchrc(void) { at_linestart = 0; pos = ReadIdentifier(pos - 1); if (macrocheck && macrotest()) @@ -1414,7 +1762,7 @@ static short tchrc() { return TK_IDENTIFIER; } -static short tchrd() { +static short tchrd(void) { at_linestart = 0; pos = ReadIdentifier(pos - 1); if (macrocheck && macrotest()) @@ -1437,7 +1785,7 @@ static short tchrd() { return TK_IDENTIFIER; } -static short tchre() { +static short tchre(void) { at_linestart = 0; pos = ReadIdentifier(pos - 1); if (macrocheck && macrotest()) @@ -1457,7 +1805,7 @@ static short tchre() { return TK_IDENTIFIER; } -static short tchrf() { +static short tchrf(void) { at_linestart = 0; pos = ReadIdentifier(pos - 1); if (macrocheck && macrotest()) @@ -1475,7 +1823,7 @@ static short tchrf() { return TK_IDENTIFIER; } -static short tchrg() { +static short tchrg(void) { at_linestart = 0; pos = ReadIdentifier(pos - 1); if (macrocheck && macrotest()) @@ -1485,7 +1833,7 @@ static short tchrg() { return TK_IDENTIFIER; } -static short tchri() { +static short tchri(void) { at_linestart = 0; pos = ReadIdentifier(pos - 1); if (macrocheck && macrotest()) @@ -1510,7 +1858,7 @@ static short tchri() { return TK_IDENTIFIER; } -static short tchrl() { +static short tchrl(void) { at_linestart = 0; pos = ReadIdentifier(pos - 1); if (macrocheck && macrotest()) @@ -1520,7 +1868,7 @@ static short tchrl() { return TK_IDENTIFIER; } -static short tchrm() { +static short tchrm(void) { at_linestart = 0; pos = ReadIdentifier(pos - 1); if (macrocheck && macrotest()) @@ -1556,7 +1904,7 @@ static short tchrn(short t) { return TK_IDENTIFIER; } -static short tchro() { +static short tchro(void) { at_linestart = 0; pos = ReadIdentifier(pos - 1); if (macrocheck && macrotest()) @@ -1598,7 +1946,7 @@ static short tchrp(short t) { return TK_IDENTIFIER; } -static short tchrr() { +static short tchrr(void) { at_linestart = 0; pos = ReadIdentifier(pos - 1); if (macrocheck && macrotest()) @@ -1617,7 +1965,7 @@ static short tchrr() { return TK_IDENTIFIER; } -static short tchrs() { +static short tchrs(void) { at_linestart = 0; pos = ReadIdentifier(pos - 1); if (macrocheck && macrotest()) @@ -1642,7 +1990,7 @@ static short tchrs() { return TK_IDENTIFIER; } -static short tchrt() { +static short tchrt(void) { at_linestart = 0; pos = ReadIdentifier(pos - 1); if (macrocheck && macrotest()) @@ -1685,7 +2033,7 @@ static short tchrt() { return TK_IDENTIFIER; } -static short tchru() { +static short tchru(void) { at_linestart = 0; pos = ReadIdentifier(pos - 1); if (macrocheck && macrotest()) @@ -1702,7 +2050,7 @@ static short tchru() { return TK_IDENTIFIER; } -static short tchrv() { +static short tchrv(void) { at_linestart = 0; pos = ReadIdentifier(pos - 1); if (macrocheck && macrotest()) @@ -1716,7 +2064,7 @@ static short tchrv() { return TK_IDENTIFIER; } -static short tchrw() { +static short tchrw(void) { at_linestart = 0; pos = ReadIdentifier(pos - 1); if (macrocheck && macrotest()) @@ -1744,7 +2092,7 @@ static short tchrx(short t) { return TK_IDENTIFIER; } -static short tchr_() { +static short tchr_(void) { at_linestart = 0; pos = ReadIdentifier(pos - 1); if (macrocheck && macrotest()) @@ -1801,7 +2149,7 @@ static short tdoll(short t) { return t; } -static short tisid() { +static short tisid(void) { if (!tokenstacklevel) CError_Error(105); return 0; @@ -1817,7 +2165,7 @@ static short tnull(short t) { } } -static short t0x1a() { +static short t0x1a(void) { if (*pos == 0) return 0; else @@ -1862,7 +2210,7 @@ static TokenizePtr cprep_tokenize[256] = { F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille), F(tille) }; -short lookahead() { +short lookahead(void) { SInt32 state; short t; @@ -1873,7 +2221,7 @@ short lookahead() { return t; } -short lookahead_noeol() { +short lookahead_noeol(void) { SInt32 state; short t; @@ -1886,14 +2234,215 @@ short lookahead_noeol() { return t; } +typedef struct StringChunk { + struct StringChunk *next; + char *data; + SInt32 offset; + SInt32 size; +} StringChunk; + static void CPrep_StringConCat(Boolean flag) { + StringPtr buffer; + StringChunk *chunks; + StringChunk *chunk; + char *saveString; + SInt32 saveSize; + SInt32 offset; + Boolean savePascalString; + TStreamElement *elem; + short ch; + + saveString = tkstring; + saveSize = tksize; + savePascalString = ispascalstring; + + cprep_strconcat = 1; + + chunks = NULL; + offset = tksize; + + while (1) { + ch = lookahead_noeol(); + if (ch != TK_STRING && ch != TK_STRING_WIDE) { + ispascalstring = savePascalString; + if (chunks) { + tksize = offset; + buffer = galloc(offset); + tkstring = (char *) buffer; + + memcpy(buffer, saveString, saveSize); + for (chunk = chunks; chunk; chunk = chunk->next) + memcpy(buffer + chunk->offset, chunk->data, chunk->size); + + if (savePascalString) { + if (offset > 256) { + CError_Error(CErrorStr106); + offset = 256; + } + buffer[0] = offset - 1; + } else if (flag) { + CMach_InitIntMem(TYPE(&stwchar), cint64_zero, buffer + offset - stwchar.size); + } else { + CMach_InitIntMem(TYPE(&stchar), cint64_zero, buffer + offset - stchar.size); + } + + elem = ts_current - 1; + elem->data.tkstring.data = (char *) buffer; + elem->data.tkstring.size = offset; + elem->subtype = ispascalstring; + cprep_strconcat = 0; + } else { + tkstring = saveString; + tksize = saveSize; + cprep_strconcat = 0; + } + break; + } + + do { + ch = lex(); + elem = --ts_current; + memmove(elem, elem + 1, sizeof(TStreamElement) * ts_preread_elements); + } while (ch == TK_NEG7); + + chunk = lalloc(sizeof(StringChunk)); + chunk->next = chunks; + chunk->data = tkstring; + chunk->size = tksize - 1; + chunk->offset = offset - 1; + chunks = chunk; + + if (ispascalstring) + chunk->data++; + if (savePascalString) + chunk->offset++; + + if (ch == TK_STRING_WIDE) + chunk->size = chunk->size + 1 - stwchar.size; + if (flag) + chunk->offset = chunk->offset + 1 - stwchar.size; + + offset += chunk->size; + } } -short lex() { +short lex(void) { + short t; + + while (1) { + if (ts_preread_elements > 0) + break; + + t = ts_current->tokentype; + if (t < 0) { + switch (t) { + case TK_INTCONST: + tkintconst = ts_current->data.tkintconst; + tksize = ts_current->subtype; + break; + case TK_FLOATCONST: + tkfloatconst = ts_current->data.tkfloatconst; + tksize = ts_current->subtype; + break; + case TK_IDENTIFIER: + tkidentifier = ts_current->data.tkidentifier; + break; + case TK_STRING: + case TK_STRING_WIDE: + tkstring = ts_current->data.tkstring.data; + tksize = ts_current->data.tkstring.size; + ispascalstring = ts_current->subtype; + break; + case TK_NEG7: + nlflag = 1; + if (!cprep_eoltokens) { + ts_current++; + ts_preread_elements--; + continue; + } + break; + default: + CError_FATAL(3007); + } + } + + ts_current++; + ts_preread_elements--; + return t; + } + + while (1) { + t = prepskipnextchar(); + + ts_current->tokenfile = prep_file; + if (tokenstacklevel > 0) { + ts_current->tokenoffset = tokenstack[0].pos - prep_file_start; + macropos = pos; + } else { + ts_current->tokenoffset = pos - prep_file_start; + } + ts_current->tokenline = linenumber; + pos = nextcharpos; + + t = cprep_tokenize[t](t); + if (t != 0) { + if (ts_current >= ts_last) + CPrep_TSBufferGrow(1024); + ts_current->tokentype = t; + + if ((t = ts_current->tokentype) < 0) { + switch (t) { + case TK_INTCONST: + ts_current->data.tkintconst = tkintconst; + ts_current->subtype = tksize; + break; + case TK_FLOATCONST: + ts_current->data.tkfloatconst = tkfloatconst; + ts_current->subtype = tksize; + break; + case TK_IDENTIFIER: + ts_current->data.tkidentifier = tkidentifier; + break; + case TK_STRING: + case TK_STRING_WIDE: + ts_current->data.tkstring.data = tkstring; + ts_current->data.tkstring.size = tksize; + ts_current->subtype = ispascalstring; + if (!cprep_strconcat) { + ts_current++; + CPrep_StringConCat(t == TK_STRING_WIDE); + return t; + } + break; + case TK_NEG6: + ts_current++; + CError_Error(CErrorStr105); + ts_current--; + break; + } + } + + ts_current++; + return t; + } + + if (*pos == 0) { + if (tokenstacklevel > 0) { + poptokenseq(); + } else if (tokenstacklevel > 0 || pos >= prep_file_end) { + if (filesp > 0) + popfile(); + else + return 0; + } else { + ts_current++; + CError_ErrorTerm(CErrorStr105); + } + } + } } -short plex() { - // does not match - global refs in wrong order +short plex(void) { short t; while (1) { @@ -1916,7 +2465,7 @@ short plex() { return 0; } -short lexidentifier() { +short lexidentifier(void) { short t; char *save_pos; diff --git a/compiler_and_linker/FrontEnd/C/CScope.c b/compiler_and_linker/FrontEnd/C/CScope.c index 06cbd6c..f15787c 100644 --- a/compiler_and_linker/FrontEnd/C/CScope.c +++ b/compiler_and_linker/FrontEnd/C/CScope.c @@ -93,7 +93,7 @@ void CScope_SetFunctionScope(Object *function, CScopeSave *save) { } } -void CScope_SetMethodScope(Object *function, TypeClass *cls, Boolean unknownFlag, CScopeSave *save) { +void CScope_SetMethodScope(Object *function, TypeClass *cls, Boolean is_static, CScopeSave *save) { save->current = cscope_current; save->currentclass = cscope_currentclass; save->currentfunc = cscope_currentfunc; @@ -102,7 +102,7 @@ void CScope_SetMethodScope(Object *function, TypeClass *cls, Boolean unknownFlag cscope_currentfunc = function; cscope_currentclass = cls; cscope_current = cls->nspace; - cscope_is_member_func = !unknownFlag; + cscope_is_member_func = !is_static; } void CScope_RestoreScope(CScopeSave *saved) { diff --git a/compiler_and_linker/unsorted/CABI.c b/compiler_and_linker/unsorted/CABI.c index 3e99ca0..91883f5 100644 --- a/compiler_and_linker/unsorted/CABI.c +++ b/compiler_and_linker/unsorted/CABI.c @@ -1,11 +1,30 @@ #include "compiler/CABI.h" +#include "compiler/CClass.h" +#include "compiler/CDecl.h" +#include "compiler/CError.h" +#include "compiler/CException.h" +#include "compiler/CExpr.h" +#include "compiler/CFunc.h" +#include "compiler/CInit.h" +#include "compiler/CInline.h" #include "compiler/CMachine.h" -#include "compiler/types.h" +#include "compiler/CMangler.h" +#include "compiler/CParser.h" +#include "compiler/CScope.h" +#include "compiler/CSOM.h" #include "compiler/CompilerTools.h" +#include "compiler/objects.h" +#include "compiler/scopes.h" +#include "compiler/types.h" -static void *trans_vtboffsets; // TODO type -static void *cabi_pathroot; // TODO type - 8 byte struct?? -static void *cabi_pathcur; // TODO type +typedef struct OffsetList { + struct OffsetList *next; + SInt32 offset; +} OffsetList; + +static OffsetList *trans_vtboffsets; +static BClassList cabi_pathroot; +static BClassList *cabi_pathcur; static TypeClass *cabi_loop_class; static Boolean cabi_loop_construct; @@ -21,21 +40,271 @@ Type *CABI_GetPtrDiffTType(void) { return (Type *) &stsignedlong; } -SInt16 CABI_StructSizeAlignValue(Type *type, SInt32 size) {} +SInt16 CABI_StructSizeAlignValue(Type *type, SInt32 size) { + SInt16 align = CMach_GetTypeAlign(type); + if (align <= 1) + return 0; + else + return (align - 1) & (align - ((size & (align - 1)))); +} + +void CABI_ReverseBitField(TypeBitfield *tbitfield) { + UInt8 bits; + UInt8 a; + UInt8 b; + + switch (tbitfield->bitfieldtype->size) { + case 1: + bits = 8; + break; + case 2: + bits = 16; + break; + case 4: + bits = 32; + break; + case 8: + bits = 64; + break; + default: + CError_FATAL(172); + } + + b = tbitfield->unkB; + a = tbitfield->unkA; + tbitfield->unkA = (bits - a) - b; +} + +static void CABI_AllocateZeroVTablePointer(void *unk, TypeClass *tclass) { + ClassList *base; + + for (base = tclass->bases; base; base = base->next) { + if (!base->is_virtual && base->base->vtable) + return; + } + + tclass->size += void_ptr.size; +} + +static SInt32 CABI_GetBaseSize(TypeClass *tclass) { + SInt32 size = tclass->size; + + if (copts.vbase_abi_v2 && tclass->vbases) + return tclass->vbases->offset; + + return size; +} + +static void CABI_AllocateBases(DeclE *decle, TypeClass *tclass) { + Boolean flag; + TypeClass *baseclass; + ClassList *base; + VClassList *vbase; + SInt32 size; + + flag = 0; + size = tclass->size; + + for (base = tclass->bases; base; base = base->next) { + if (!base->is_virtual) { + baseclass = base->base; + if (!(baseclass->flags & CLASS_FLAGS_1000)) { + base->offset = size + CMach_MemberAlignValue(TYPE(baseclass), size); + if (copts.vbase_abi_v2) { + size = base->offset + CABI_GetBaseSize(baseclass); + } else { + size = base->offset + baseclass->size; + for (vbase = baseclass->vbases; vbase; vbase = vbase->next) + size -= vbase->base->size; + } + flag = 0; + } else { + if (flag) + base->offset = ++size; + else + base->offset = size; + flag = 1; + } + } + } + + tclass->size = size; +} + +static void CABI_AllocateVirtualBasePointers(DeclE *decle, TypeClass *tclass) { + ClassList *base; + SInt32 size; + + size = tclass->size; + + for (base = tclass->bases; base; base = base->next) { + if (base->is_virtual) { + base->offset = size + CMach_MemberAlignValue(TYPE(&void_ptr), size); + size = base->offset + void_ptr.size; + } + } + + tclass->size = size; +} -void CABI_ReverseBitField(TypeBitfield *tbitfield) {} +static SInt32 CABI_GetMemberOffset(TypeClass *tclass, HashNameNode *name) { + ObjMemberVar *ivar; -// not sure about the sig for this, it's unused lmao -static void CABI_AllocateZeroVTablePointer() {} + if (!name) + return 0; + + ivar = tclass->ivars; + while (1) { + if (ivar->name == name) + return ivar->offset; + + if (!(ivar = ivar->next)) + CError_FATAL(362); + } +} + +static void CABI_AllocateMembers(DeclE *decle, TypeClass *tclass) { + ObjMemberVar *ivar; + SInt32 initialSize; + SInt32 maxSize; + TypeClass *unionClass; + SInt32 unionStart; + Boolean inAnonUnion; + Boolean removeNoNameIvars; + + removeNoNameIvars = 0; + initialSize = maxSize = tclass->size; + CMach_StructLayoutInitOffset(maxSize); + + unionClass = NULL; + for (ivar = tclass->ivars; ivar; ivar = ivar->next) { + if (!ivar->anonunion) { + if (!(ivar->offset & 0x80000000)) { + if (tclass->mode == CLASS_MODE_1) + CMach_StructLayoutInitOffset(initialSize); + + if (IS_TYPE_BITFIELD(ivar->type)) + ivar->offset = CMach_StructLayoutBitfield(TYPE_BITFIELD(ivar->type), ivar->qual); + else + ivar->offset = CMach_StructLayoutGetOffset(ivar->type, ivar->qual); + + if (tclass->mode == CLASS_MODE_1) { + SInt32 tmp = CMach_StructLayoutGetCurSize(); + if (tmp > maxSize) + maxSize = tmp; + } + + unionClass = NULL; + } else { + CError_ASSERT(412, unionClass); + ivar->offset = unionStart + CABI_GetMemberOffset(unionClass, ivar->name); + if (!inAnonUnion) + ivar->anonunion = 1; + inAnonUnion = 0; + } + + if (ivar->name == no_name_node || ivar->name == NULL) + removeNoNameIvars = 1; + } else { + CError_ASSERT(422, IS_TYPE_CLASS(ivar->type)); + + if (tclass->mode == CLASS_MODE_1) + CMach_StructLayoutInitOffset(initialSize); + + unionStart = CMach_StructLayoutGetOffset(ivar->type, ivar->qual); + unionClass = TYPE_CLASS(ivar->type); + inAnonUnion = 1; + + if (tclass->mode == CLASS_MODE_1) { + SInt32 tmp = CMach_StructLayoutGetCurSize(); + if (tmp > maxSize) + maxSize = tmp; + } + + removeNoNameIvars = 1; + } + + if (decle->vtable_ivar == ivar) + tclass->vtable->offset = ivar->offset; + } + + if (removeNoNameIvars) { + ObjMemberVar **ptr = &tclass->ivars; + while (*ptr) { + if ((*ptr)->name == NULL || (*ptr)->name == no_name_node) + *ptr = (*ptr)->next; + else + ptr = &(*ptr)->next; + } + } + + if (tclass->mode == CLASS_MODE_1) + tclass->size = maxSize; + else + tclass->size = CMach_StructLayoutGetCurSize(); + + if (copts.reverse_bitfields) { + for (ivar = tclass->ivars; ivar; ivar = ivar->next) { + if (IS_TYPE_BITFIELD(ivar->type)) + CABI_ReverseBitField(TYPE_BITFIELD(ivar->type)); + } + } +} + +static void CABI_AllocateVirtualBases(DeclE *decle, TypeClass *tclass) { + VClassList *vbase; + SInt32 size; + + size = tclass->size; + + for (vbase = tclass->vbases; vbase; vbase = vbase->next) { + vbase->offset = size + CMach_MemberAlignValue(TYPE(vbase->base), size); + size = vbase->offset + CABI_GetBaseSize(vbase->base); + + if (vbase->has_override) + size += CMach_MemberAlignValue(TYPE(&stunsignedlong), size) + 4; + } + + tclass->size = size; +} -static SInt32 CABI_GetBaseSize(TypeClass *tclass) {} -static void CABI_AllocateBases() {} -static void CABI_AllocateVirtualBasePointers() {} -static void CABI_GetMemberOffset() {} -static void CABI_AllocateMembers() {} -static void CABI_AllocateVirtualBases() {} -static void CABI_FindZeroDeltaVPtr() {} -static void CABI_FindZeroVirtualBaseMember() {} +static Boolean CABI_FindZeroDeltaVPtr(TypeClass *tclass) { + ClassList *base; + + for (base = tclass->bases; base; base = base->next) { + if (!base->is_virtual && base->base->vtable && !base->offset) { + tclass->vtable->offset = base->base->vtable->offset; + return 1; + } + } + + return 0; +} + +static Object *CABI_FindZeroVirtualBaseMember(TypeClass *tclass, Object *obj) { + NameSpaceObjectList *nsol; + ClassList *base; + Object *chk; + + for (base = tclass->bases; base; base = base->next) { + if (!base->is_virtual && !base->offset && !base->voffset && base->base->vtable) { + for (nsol = CScope_FindName(base->base->nspace, obj->name); nsol; nsol = nsol->next) { + chk = OBJECT(nsol->object); + if ( + chk->otype == OT_OBJECT && + chk->datatype == DVFUNC && + CClass_GetOverrideKind(TYPE_FUNC(chk->type), TYPE_FUNC(obj->type), 0) == 1 + ) + return chk; + } + + if ((chk = CABI_FindZeroVirtualBaseMember(base->base, obj))) + return chk; + } + } + + return NULL; +} void CABI_AddVTable(TypeClass *tclass) { tclass->vtable = galloc(sizeof(VTable)); @@ -46,48 +315,1714 @@ SInt32 CABI_GetVTableOffset(TypeClass *tclass) { return 0; } -static void CABI_GetBaseVTableSize() {} -static void CABI_ApplyClassFlags() {} -static void CABI_AllocateVTable() {} -void CABI_LayoutClass(DeclE *decle, TypeClass *tclass) {} -void CABI_MakeDefaultArgConstructor(TypeClass *tclass, Object *obj) {} -static void CABI_ThisArg() {} -ENode *CABI_MakeThisExpr(TypeClass *tclass, SInt32 offset) {} -static void CABI_VArg() {} -static void CABI_MakeVArgExpr() {} -static void CABI_MakeCopyConArgExpr() {} -static void CABI_InitVBasePtr1() {} -static void CABI_InitVBasePtrs() {} -static void CABI_GetVBasePath() {} -static void CABI_GetVBasePtr() {} -static SInt32 CABI_FindNVBase(TypeClass *tclass, TypeClass *base, SInt32 offset) {} -SInt32 CABI_GetCtorOffsetOffset(TypeClass *tclass, TypeClass *base) {} -static void CABI_InitVBaseCtorOffsets() {} -static void CABI_InitVTablePtrs() {} -static Boolean CABI_IsOperatorNew(Object *obj) {} -Object *CABI_ConstructorCallsNew(TypeClass *tclass) {} -void CABI_TransConstructor(Object *obj, Statement *stmt, TypeClass *tclass, TransConstructorCallback callback, Boolean flag) {} -void CABI_MakeDefaultConstructor(TypeClass *tclass, Object *obj) {} -static void CABI_AssignObject() {} -static void CABI_FindIntegralSizeType() {} -static void CABI_AppendCopyRegion() {} -static void CABI_ClassInitLoopCallBack() {} -static void CABI_CopyConAssignCB() {} -void CABI_MakeDefaultCopyConstructor(TypeClass *tclass, Object *obj) {} -void CABI_MakeDefaultAssignmentOperator(TypeClass *tclass, Object *obj) {} -static void CABI_DestroyMembers() {} -static void CABI_DestroyBases() {} -static void CABI_DestroyVBases() {} -void CABI_TransDestructor(Object *obj1, Object *obj2, Statement *stmt, TypeClass *tclass) {} -void CABI_MakeDefaultDestructor(TypeClass *tclass, Object *obj) {} -static void CABI_CreateLayeredDestructor() {} -void CABI_MakeLayeredDestructor(TypeClass *tclass, Object *obj) {} - -Object *CABI_GetDestructorObject(Object *obj, int what) { +static SInt32 CABI_GetBaseVTableSize(TypeClass *tclass) { + VClassList *vbase; + SInt32 size; + + size = tclass->vtable->size; + + for (vbase = tclass->vbases; vbase; vbase = vbase->next) { + if (vbase->base->vtable) + size -= CABI_GetBaseVTableSize(vbase->base); + } + + return size; +} + +static void CABI_ApplyClassFlags(Object *obj, UInt8 flags, Boolean unused) { + if (flags & CLASS_EFLAGS_INTERNAL) + obj->flags |= OBJECT_FLAGS_10; + if (flags & CLASS_EFLAGS_IMPORT) + obj->flags |= OBJECT_FLAGS_20; + if (flags & CLASS_EFLAGS_EXPORT) + obj->flags |= OBJECT_FLAGS_40; +} + +static void CABI_AllocateVTable(DeclE *decle, TypeClass *tclass) { + SInt32 size; + ObjBase *objbase; + Object *obj; + ObjMemberVar *ivar; + ClassList *base; + VClassList *vbase; + int i; + + size = 0; + + if (!tclass->vtable) { + CABI_AddVTable(tclass); + decle->xA = decle->x8 - 1; + } + + if (!CABI_FindZeroDeltaVPtr(tclass)) { + ivar = galloc(sizeof(ObjMemberVar)); + memclrw(ivar, sizeof(ObjMemberVar)); + + ivar->otype = OT_MEMBERVAR; + ivar->access = ACCESSPUBLIC; + ivar->name = vptr_name_node; + ivar->type = TYPE(&void_ptr); + decle->vtable_ivar = ivar; + + for (i = decle->xA; ; i--) { + if (i < 0) { + ivar->next = tclass->ivars; + tclass->ivars = ivar; + break; + } + + CError_ASSERT(666, decle->objlist[i]); + + if (decle->objlist[i]->otype == OT_MEMBERVAR) { + ivar->next = OBJ_MEMBER_VAR(decle->objlist[i])->next; + OBJ_MEMBER_VAR(decle->objlist[i])->next = ivar; + break; + } + } + + if (tclass->flags & (CLASS_FLAGS_10 | CLASS_FLAGS_2000)) + size = void_ptr.size; + else + size = 8; + } else { + decle->vtable_ivar = NULL; + } + + for (base = tclass->bases; base; base = base->next) { + if (base->base->vtable && !base->is_virtual) { + base->voffset = size; + if (copts.vbase_abi_v2) { + size += CABI_GetBaseVTableSize(base->base); + } else { + size += base->base->vtable->size; + for (vbase = base->base->vbases; vbase; vbase = vbase->next) { + if (vbase->base->vtable) + size -= vbase->base->vtable->size; + } + } + } + } + + for (i = 0; i < decle->x8; i++) { + CError_ASSERT(714, objbase = decle->objlist[i]); + + if (objbase->otype == OT_OBJECT && OBJECT(objbase)->datatype == DVFUNC) { + TypeMethod *tmethod = TYPE_METHOD(OBJECT(objbase)->type); + Object *baseobj = CABI_FindZeroVirtualBaseMember(tclass, OBJECT(objbase)); + + if (baseobj) { + tmethod->x1E = TYPE_METHOD(baseobj->type)->x1E; + } else { + tmethod->x1E = size; + size += 4; + } + } + } + + for (vbase = tclass->vbases; vbase; vbase = vbase->next) { + if (vbase->base->vtable) { + vbase->voffset = size; + if (copts.vbase_abi_v2) + size += CABI_GetBaseVTableSize(vbase->base); + else + size += vbase->base->vtable->size; + } + } + + obj = CParser_NewCompilerDefDataObject(); + CABI_ApplyClassFlags(obj, tclass->eflags, 0); + + obj->name = CMangler_VTableName(tclass); + obj->type = CDecl_NewStructType(size, 4); + obj->qual = Q_CONST; + obj->nspace = tclass->nspace; + switch (tclass->action) { + case CLASS_ACTION_0: + obj->sclass = TK_STATIC; + obj->qual |= Q_20000; + break; + } + + CParser_UpdateObject(obj, NULL); + + tclass->vtable->object = obj; + tclass->vtable->owner = tclass; + tclass->vtable->size = size; +} + +void CABI_LayoutClass(DeclE *decle, TypeClass *tclass) { + char saveAlignMode = copts.align_mode; + + tclass->size = 0; + if (!tclass->sominfo) { + if (tclass->bases) + CABI_AllocateBases(decle, tclass); + if (tclass->flags & CLASS_FLAGS_20) + CABI_AllocateVirtualBasePointers(decle, tclass); + if (decle->xC) + CABI_AllocateVTable(decle, tclass); + CABI_AllocateMembers(decle, tclass); + if (tclass->flags & CLASS_FLAGS_20) + CABI_AllocateVirtualBases(decle, tclass); + } else { + copts.align_mode = AlignMode2_PPC; + CABI_AllocateMembers(decle, tclass); + } + + tclass->align = CMach_GetClassAlign(tclass); + if (tclass->size == 0) { + tclass->size = 1; + tclass->flags |= CLASS_FLAGS_1000; + } else { + tclass->size += CABI_StructSizeAlignValue(TYPE(tclass), tclass->size); + } + + tclass->flags |= CLASS_FLAGS_2; + + copts.align_mode = saveAlignMode; +} + +void CABI_MakeDefaultArgConstructor(TypeClass *tclass, Object *func) { + DefArgCtorInfo *info; + Boolean saveDebugInfo; + ENodeList *copied; + FuncArg *args; + ENodeList *argexprs; + CScopeSave savedScope; + Statement firstStmt; + Statement returnStmt; + + CError_FATAL(860); + + if (anyerrors || func->access == ACCESSNONE) + return; + + CError_ASSERT(866, info = func->u.func.defargdata); + + CABI_ApplyClassFlags(func, tclass->eflags, 0); + + CScope_SetFunctionScope(func, &savedScope); + + CFunc_FuncGenSetup(&firstStmt, func); + + saveDebugInfo = copts.isGeneratingDebugInfo; + copts.isGeneratingDebugInfo = 0; + + CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args); + + if (tclass->flags & CLASS_FLAGS_20) + arguments->next->object->name = no_name_node; + + firstStmt.next = &returnStmt; + + memclrw(&returnStmt, sizeof(Statement)); + returnStmt.type = ST_RETURN; + returnStmt.expr = lalloc(sizeof(ENode)); + returnStmt.expr->type = EFUNCCALL; + returnStmt.expr->cost = 200; + returnStmt.expr->flags = 0; + returnStmt.expr->rtype = TYPE(&void_ptr); + + returnStmt.expr->data.funccall.funcref = CExpr_MakeObjRefNode(info->default_func, 0); + returnStmt.expr->data.funccall.functype = TYPE_FUNC(info->default_func->type); + args = TYPE_FUNC(info->default_func->type)->args; + returnStmt.expr->data.funccall.args = lalloc(sizeof(ENodeList)); + argexprs = returnStmt.expr->data.funccall.args; + + argexprs->node = create_objectnode(arguments->object); + + if (tclass->flags & CLASS_FLAGS_20) { + args = args->next; + argexprs->next = lalloc(sizeof(ENodeList)); + argexprs = argexprs->next; + argexprs->node = create_objectnode(arguments->next->object); + } + + args = args->next; + argexprs->next = lalloc(sizeof(ENodeList)); + argexprs = argexprs->next; + argexprs->node = CInline_CopyExpression(info->default_arg, CopyMode0); + + while ((args = args->next) && args->dexpr) { + argexprs->next = lalloc(sizeof(ENodeList)); + argexprs = argexprs->next; + argexprs->node = CInline_CopyExpression(args->dexpr, CopyMode0); + } + + argexprs->next = NULL; + + CFunc_CodeCleanup(&firstStmt); + CFunc_Gen(&firstStmt, func, 0); + + CScope_RestoreScope(&savedScope); + copts.isGeneratingDebugInfo = saveDebugInfo; + + func->u.func.defargdata = NULL; +} + +static Object *CABI_ThisArg(void) { + CError_ASSERT(931, arguments && IS_TYPE_POINTER_ONLY(arguments->object->type)); + return arguments->object; +} + +ENode *CABI_MakeThisExpr(TypeClass *tclass, SInt32 offset) { + ENode *expr; + + if (tclass) { + if (!tclass->sominfo) { + expr = create_objectnode(CABI_ThisArg()); + if (tclass->flags & CLASS_FLAGS_1) + expr = makemonadicnode(expr, EINDIRECT); + } else { + expr = CSOM_SOMSelfObjectExpr(tclass); + } + } else { + expr = create_objectnode(CABI_ThisArg()); + expr->rtype = TYPE(&void_ptr); + } + + if (offset) + expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), offset), EADD); + + return expr; +} + +static Object *CABI_VArg(void) { + CError_ASSERT(976, arguments && arguments->next && IS_TYPE_INT(arguments->next->object->type)); + return arguments->next->object; +} + +static ENode *CABI_MakeVArgExpr(void) { + return create_objectnode(CABI_VArg()); +} + +static ENode *CABI_MakeCopyConArgExpr(TypeClass *tclass, Boolean flag) { + ObjectList *args; + + CError_ASSERT(1000, args = arguments); + CError_ASSERT(1001, args = args->next); + if (flag && (tclass->flags & CLASS_FLAGS_20)) + CError_ASSERT(1002, args = args->next); + CError_ASSERT(1003, IS_TYPE_POINTER_ONLY(args->object->type)); + + return create_objectnode(args->object); +} + +static ENode *CABI_InitVBasePtr1(ENode *expr, TypeClass *tclass1, TypeClass *tclass2, TypeClass *tclass3, SInt32 offset) { + ClassList *base; + SInt32 newOffset; + OffsetList *list; + + for (base = tclass2->bases; base; base = base->next) { + if (base->base == tclass3 && base->is_virtual) { + newOffset = offset + base->offset; + + for (list = trans_vtboffsets; list; list = list->next) { + if (newOffset == list->offset) + break; + } + + if (!list) { + list = lalloc(sizeof(OffsetList)); + list->offset = newOffset; + list->next = trans_vtboffsets; + trans_vtboffsets = list; + + expr = makediadicnode( + makemonadicnode(CABI_MakeThisExpr(NULL, newOffset), EINDIRECT), + expr, + EASS); + } + } + + if (base->is_virtual) + newOffset = CClass_VirtualBaseOffset(tclass1, base->base); + else + newOffset = offset + base->offset; + + expr = CABI_InitVBasePtr1(expr, tclass1, base->base, tclass3, newOffset); + } + + return expr; +} + +static Statement *CABI_InitVBasePtrs(Statement *stmt, TypeClass *tclass) { + ENode *expr; + VClassList *vbase; + + for (vbase = tclass->vbases, trans_vtboffsets = NULL; vbase; vbase = vbase->next) { + expr = CABI_InitVBasePtr1(CABI_MakeThisExpr(NULL, vbase->offset), tclass, tclass, vbase->base, 0); + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + stmt->expr = expr; + } + + return stmt; +} + +static OffsetList *CABI_GetVBasePath(TypeClass *tclass, TypeClass *baseclass) { + ClassList *base; + OffsetList *best; + OffsetList *list; + OffsetList *scan; + short bestLength; + short length; + + for (base = tclass->bases; base; base = base->next) { + if (base->base == baseclass && base->is_virtual) { + best = lalloc(sizeof(OffsetList)); + best->next = NULL; + best->offset = base->offset; + return best; + } + } + + best = NULL; + + for (base = tclass->bases; base; base = base->next) { + if ((list = CABI_GetVBasePath(base->base, baseclass))) { + for (scan = list->next, length = 1; scan; scan = scan->next) + length++; + + if (base->is_virtual) + length++; + + if (!best || length < bestLength) { + if (base->is_virtual) { + best = lalloc(sizeof(OffsetList)); + best->next = list; + best->offset = base->offset; + } else { + best = list; + best->offset += base->offset; + } + bestLength = length; + } + } + } + + return best; +} + +static ENode *CABI_GetVBasePtr(TypeClass *tclass, TypeClass *baseclass) { + OffsetList *path; + ENode *expr; + + CError_ASSERT(1127, path = CABI_GetVBasePath(tclass, baseclass)); + + expr = makemonadicnode(CABI_MakeThisExpr(NULL, path->offset), EINDIRECT); + + while ((path = path->next)) { + if (path->offset) + expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), path->offset), EADD); + expr = makemonadicnode(expr, EINDIRECT); + } + + return expr; +} + +static SInt32 CABI_FindNVBase(TypeClass *tclass, TypeClass *baseclass, SInt32 offset) { + ClassList *base; + SInt32 tmp; + + if (tclass == baseclass) + return offset; + + for (base = tclass->bases; base; base = base->next) { + if (!base->is_virtual && (tmp = CABI_FindNVBase(base->base, baseclass, offset + base->offset)) >= 0) + return tmp; + } + + return -1; +} + +SInt32 CABI_GetCtorOffsetOffset(TypeClass *tclass, TypeClass *baseclass) { + SInt32 baseSize; + SInt32 size; + char saveAlignMode; + + size = CABI_GetBaseSize(tclass); + if (baseclass) { + baseSize = CABI_FindNVBase(tclass, baseclass, 0); + CError_ASSERT(1178, baseSize >= 0); + size -= baseSize; + } + + saveAlignMode = copts.align_mode; + if (tclass->eflags & CLASS_EFLAGS_F0) + copts.align_mode = ((tclass->eflags & CLASS_EFLAGS_F0) >> 4) - 1; + size += CMach_MemberAlignValue(TYPE(&stunsignedlong), size); + copts.align_mode = saveAlignMode; + + return size; +} + +static Statement *CABI_InitVBaseCtorOffsets(Statement *stmt, TypeClass *tclass) { + VClassList *vbase; + Object *tempObj; + ENode *expr; + ENode *vbaseptr; + SInt32 vboffset; + SInt32 ctorOffsetOffset; + + tempObj = NULL; + + for (vbase = tclass->vbases; vbase; vbase = vbase->next) { + if (vbase->has_override) { + if (!tempObj) + tempObj = create_temp_object(TYPE(&void_ptr)); + + vboffset = CClass_VirtualBaseOffset(tclass, vbase->base); + ctorOffsetOffset = CABI_GetCtorOffsetOffset(vbase->base, NULL); + vbaseptr = CABI_GetVBasePtr(tclass, vbase->base); + CError_ASSERT(1215, vbaseptr); + + expr = makediadicnode(create_objectnode(tempObj), vbaseptr, EASS); + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + stmt->expr = expr; + + expr = makediadicnode( + create_objectnode(tempObj), + intconstnode(TYPE(&stunsignedlong), ctorOffsetOffset), + EADD); + expr = makemonadicnode(expr, EINDIRECT); + expr->rtype = TYPE(&stunsignedlong); + expr = makediadicnode( + expr, + makediadicnode( + CABI_MakeThisExpr(NULL, vboffset), + create_objectnode(tempObj), + ESUB), + EASS); + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + stmt->expr = expr; + } + } + + return stmt; +} + +static Statement *CABI_InitVTablePtrs(Statement *stmt, Object *vtableObj, TypeClass *tclass, TypeClass *baseclass, SInt32 offset, SInt32 voffset) { + ClassList *base; + BClassList *orig_pathcur; + SInt32 newOffset; + SInt32 newVOffset; + OffsetList *offsetList; + SInt32 vtblOffset; + ENode *vtblExpr; + ENode *pathExpr; + BClassList path; + + if (baseclass->vtable->owner == baseclass) { + vtblOffset = offset + baseclass->vtable->offset; + for (offsetList = trans_vtboffsets; offsetList; offsetList = offsetList->next) { + if (vtblOffset == offsetList->offset) + break; + } + + if (!offsetList) { + offsetList = lalloc(sizeof(OffsetList)); + offsetList->offset = vtblOffset; + offsetList->next = trans_vtboffsets; + trans_vtboffsets = offsetList; + + vtblExpr = create_objectrefnode(vtableObj); + vtblExpr->rtype = TYPE(&void_ptr); + if ((vtblOffset = voffset + CABI_GetVTableOffset(baseclass))) + vtblExpr = makediadicnode(vtblExpr, intconstnode(TYPE(&stunsignedlong), vtblOffset), EADD); + + pathExpr = CClass_AccessPathCast(&cabi_pathroot, CABI_MakeThisExpr(tclass, 0), 0); + if (baseclass->vtable->offset && !canadd(pathExpr, baseclass->vtable->offset)) { + pathExpr = makediadicnode(pathExpr, intconstnode(TYPE(&stunsignedlong), baseclass->vtable->offset), EADD); + optimizecomm(pathExpr); + } + + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + stmt->expr = makediadicnode(makemonadicnode(pathExpr, EINDIRECT), vtblExpr, EASS); + } + } + + for (base = baseclass->bases; base; base = base->next) { + if (base->base->vtable) { + orig_pathcur = cabi_pathcur; + + cabi_pathcur->next = &path; + path.next = NULL; + path.type = TYPE(base->base); + cabi_pathcur = &path; + + if (base->is_virtual) { + newOffset = CClass_VirtualBaseOffset(tclass, base->base); + newVOffset = CClass_VirtualBaseVTableOffset(tclass, base->base); + } else { + newOffset = offset + base->offset; + newVOffset = voffset + base->voffset; + } + + stmt = CABI_InitVTablePtrs(stmt, vtableObj, tclass, base->base, newOffset, newVOffset); + + cabi_pathcur = orig_pathcur; + } + } + + return stmt; +} + +static Boolean CABI_IsOperatorNew(ObjBase *obj) { + return + obj->otype == OT_OBJECT && + IS_TYPE_FUNC(OBJECT(obj)->type) && + TYPE_FUNC(OBJECT(obj)->type)->args && + TYPE_FUNC(OBJECT(obj)->type)->args->type == CABI_GetSizeTType() && + !TYPE_FUNC(OBJECT(obj)->type)->args->next; +} + +Object *CABI_ConstructorCallsNew(TypeClass *tclass) { + NameSpaceObjectList *nsol; + CScopeParseResult pr; + + if (!tclass->sominfo && (tclass->flags & CLASS_FLAGS_1)) { + if (CScope_FindClassMemberObject(tclass, &pr, CMangler_OperatorName(TK_NEW))) { + if (pr.obj_10) { + if (CABI_IsOperatorNew(pr.obj_10)) + return OBJECT(pr.obj_10); + } else { + for (nsol = pr.nsol_14; nsol; nsol = nsol->next) { + if (CABI_IsOperatorNew(nsol->object)) + return OBJECT(nsol->object); + } + } + } + + return newh_func; + } + + return NULL; +} + +void CABI_TransConstructor(Object *obj, Statement *firstStmt, TypeClass *tclass, TransConstructorCallback callback, Boolean has_try) { + Statement *stmt; + Object *tmpfunc; + Object *tmpfunc2; + CLabel *label; + ENode *expr; + ClassList *base; + VClassList *vbase; + ObjMemberVar *ivar; + Type *type; + CtorChain *chain; + Boolean errorflag; + + stmt = firstStmt; + + if ((tmpfunc = CABI_ConstructorCallsNew(tclass))) { + label = newlabel(); + + stmt = CFunc_InsertStatement(ST_IFGOTO, firstStmt); + stmt->expr = CABI_MakeThisExpr(NULL, 0); + stmt->label = label; + + expr = makediadicnode( + CABI_MakeThisExpr(NULL, 0), + funccallexpr(tmpfunc, intconstnode(CABI_GetSizeTType(), tclass->size), NULL, NULL, NULL), + EASS); + stmt = CFunc_InsertStatement(ST_IFGOTO, stmt); + stmt->expr = expr; + stmt->label = label; + + stmt = CFunc_InsertStatement(ST_RETURN, stmt); + stmt->expr = NULL; + + stmt = CFunc_InsertStatement(ST_LABEL, stmt); + stmt->label = label; + label->stmt = stmt; + } + + if (has_try) { + for (stmt = firstStmt; ; stmt = stmt->next) { + CError_ASSERT(1408, stmt); + if (stmt->type == ST_BEGINCATCH) + break; + } + } + + if (!tclass->sominfo) { + if (tclass->flags & CLASS_FLAGS_20) { + label = newlabel(); + + stmt = CFunc_InsertStatement(ST_IFGOTO, stmt); + stmt->expr = CExpr_New_EEQU_Node(CABI_MakeVArgExpr(), intconstnode(TYPE(&stsignedshort), 0)); + stmt->label = label; + + stmt = CABI_InitVBasePtrs(stmt, tclass); + + for (vbase = tclass->vbases; vbase; vbase = vbase->next) { + if (!callback) { + for (chain = ctor_chain; chain; chain = chain->next) { + if (chain->what == CtorChain_VBase && chain->u.vbase == vbase) + break; + } + + if (chain) { + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + stmt->expr = chain->objexpr; + } else { + expr = CClass_DefaultConstructorCall( + vbase->base, + tclass, + CABI_MakeThisExpr(NULL, vbase->offset), + 0, 1, 1, &errorflag); + if (expr) { + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + stmt->expr = expr; + } else if (errorflag) { + CError_Error(CErrorStr213, tclass, 0, vbase->base, 0); + } + } + } else { + stmt = callback(stmt, tclass, vbase->base, vbase->offset, 1); + } + + if ((tmpfunc = CClass_Destructor(vbase->base))) + CExcept_RegisterMember(stmt, CABI_ThisArg(), vbase->offset, tmpfunc, CABI_VArg(), 0); + } + + stmt = CFunc_InsertStatement(ST_LABEL, stmt); + stmt->label = label; + label->stmt = stmt; + } + + for (base = tclass->bases; base; base = base->next) { + if (base->is_virtual) + continue; + + if (!callback) { + for (chain = ctor_chain; chain; chain = chain->next) { + if (chain->what == CtorChain_Base && chain->u.base == base) + break; + } + + if (chain) { + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + stmt->expr = chain->objexpr; + } else { + expr = CClass_DefaultConstructorCall( + base->base, + tclass, + CABI_MakeThisExpr(NULL, base->offset), + 0, 1, 0, &errorflag); + if (expr) { + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + stmt->expr = expr; + } else if (errorflag) { + CError_Error(CErrorStr213, tclass, 0, base->base, 0); + } + } + } else { + stmt = callback(stmt, tclass, base->base, base->offset, 1); + } + + if ((tmpfunc = CClass_Destructor(base->base))) + CExcept_RegisterMember(stmt, CABI_ThisArg(), base->offset, tmpfunc, NULL, 0); + } + + if (tclass->vtable && tclass->vtable->object && tclass->vtable->owner == tclass) { + cabi_pathroot.next = NULL; + cabi_pathroot.type = TYPE(tclass); + cabi_pathcur = &cabi_pathroot; + trans_vtboffsets = NULL; + + stmt = CABI_InitVTablePtrs(stmt, tclass->vtable->object, tclass, tclass, 0, 0); + } + } + + if (!tclass->sominfo && (tclass->flags & CLASS_FLAGS_8000)) + stmt = CABI_InitVBaseCtorOffsets(stmt, tclass); + + if (!callback) { + for (ivar = tclass->ivars; ivar; ivar = ivar->next) { + for (chain = ctor_chain; chain; chain = chain->next) { + if (chain->what == CtorChain_MemberVar && chain->u.membervar == ivar) { + if (IS_TYPE_ARRAY(ivar->type)) + chain = NULL; + break; + } + } + + if (chain) { + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + stmt->expr = chain->objexpr; + type = ivar->type; + switch (type->type) { + case TYPEARRAY: + do { + type = TPTR_TARGET(type); + } while (IS_TYPE_ARRAY(type)); + if (IS_TYPE_CLASS(type)) { + if ((tmpfunc = CClass_Destructor(TYPE_CLASS(type)))) { + CError_ASSERT(1560, type->size); + CExcept_RegisterMemberArray( + stmt, + CABI_ThisArg(), + ivar->offset, + tmpfunc, + ivar->type->size / type->size, + type->size); + } + } + break; + case TYPECLASS: + if ((tmpfunc = CClass_Destructor(TYPE_CLASS(type)))) { + CExcept_RegisterMember( + stmt, + CABI_ThisArg(), + ivar->offset, + tmpfunc, + NULL, + 1); + } + break; + } + } else { + type = ivar->type; + switch (type->type) { + case TYPEARRAY: + do { + type = TPTR_TARGET(type); + } while (IS_TYPE_ARRAY(type)); + if (IS_TYPE_CLASS(type) && CClass_Constructor(TYPE_CLASS(type))) { + if ( + (tmpfunc = CClass_DefaultConstructor(TYPE_CLASS(type))) || + (tmpfunc = CClass_DummyDefaultConstructor(TYPE_CLASS(type))) + ) + { + tmpfunc2 = CClass_Destructor(TYPE_CLASS(type)); + if (tmpfunc2) + tmpfunc2 = CABI_GetDestructorObject(tmpfunc2, 1); + + stmt = CInit_ConstructClassArray( + stmt, + TYPE_CLASS(type), + tmpfunc, + tmpfunc2, + CABI_MakeThisExpr(tclass, ivar->offset), + ivar->type->size / type->size); + + if (tmpfunc2) + CExcept_RegisterMemberArray( + stmt, + CABI_ThisArg(), + ivar->offset, + tmpfunc2, + ivar->type->size / type->size, + type->size); + } else { + CError_Error(CErrorStr214, tclass, 0, ivar->name->name); + } + } + break; + case TYPECLASS: + expr = CClass_DefaultConstructorCall( + TYPE_CLASS(type), + NULL, + CABI_MakeThisExpr(tclass, ivar->offset), + 1, 1, 0, &errorflag); + if (expr) { + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + stmt->expr = expr; + } else if (errorflag) { + CError_Error(CErrorStr214, tclass, 0, ivar->name->name); + } + + if ((tmpfunc = CClass_Destructor(TYPE_CLASS(type)))) { + if (!expr) { + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + stmt->expr = nullnode(); + } + CExcept_RegisterMember( + stmt, + CABI_ThisArg(), + ivar->offset, + tmpfunc, + NULL, + 1); + } + break; + } + } + } + } else { + stmt = callback(stmt, tclass, NULL, 0, 1); + } + + if (!tclass->sominfo) { + for (stmt = firstStmt->next; stmt; stmt = stmt->next) { + if (stmt->type == ST_RETURN) { + CError_ASSERT(1661, !stmt->expr); + stmt->expr = CABI_MakeThisExpr(NULL, 0); + } + } + } +} + +void CABI_MakeDefaultConstructor(TypeClass *tclass, Object *func) { + Boolean saveDebugInfo; + CScopeSave savedScope; + Statement firstStmt; + Statement returnStmt; + + if (anyerrors || func->access == ACCESSNONE) + return; + + CABI_ApplyClassFlags(func, tclass->eflags, 0); + + CScope_SetFunctionScope(func, &savedScope); + + CFunc_FuncGenSetup(&firstStmt, func); + + saveDebugInfo = copts.isGeneratingDebugInfo; + copts.isGeneratingDebugInfo = 0; + + CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args); + + ctor_chain = NULL; + if (tclass->flags & CLASS_FLAGS_20) + arguments->next->object->name = CParser_GetUniqueName(); + + firstStmt.next = &returnStmt; + + memclrw(&returnStmt, sizeof(Statement)); + returnStmt.type = ST_RETURN; + + CABI_TransConstructor(func, &firstStmt, tclass, NULL, 0); + + CFunc_CodeCleanup(&firstStmt); + CFunc_Gen(&firstStmt, func, 0); + + CScope_RestoreScope(&savedScope); + copts.isGeneratingDebugInfo = saveDebugInfo; +} + +static ENode *CABI_AssignObject(TypeClass *tclass, ENode *expr1, ENode *expr2) { + Object *assignfunc; + FuncArg *arg; + + assignfunc = CClass_AssignmentOperator(tclass); + if (!assignfunc) { + expr1 = makemonadicnode(expr1, EINDIRECT); + expr1->rtype = TYPE(tclass); + return makediadicnode(expr1, expr2, EASS); + } + + CError_ASSERT(1731, + IS_TYPE_FUNC(assignfunc->type) && + (arg = TYPE_FUNC(assignfunc->type)->args) && + (arg = arg->next)); + + expr2 = argumentpromotion(expr2, arg->type, arg->qual, 1); + return funccallexpr(assignfunc, expr1, expr2, NULL, NULL); +} + +static Type *CABI_FindIntegralSizeType(SInt32 size) { + if (stunsignedchar.size == size) + return TYPE(&stunsignedchar); + if (stunsignedshort.size == size) + return TYPE(&stunsignedshort); + if (stunsignedint.size == size) + return TYPE(&stunsignedint); + if (stunsignedlong.size == size) + return TYPE(&stunsignedlong); + if (stunsignedlonglong.size == size) + return TYPE(&stunsignedlonglong); + + CError_FATAL(1756); + return NULL; +} + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +typedef struct CopyRegion { + struct CopyRegion *next; + Type *type; + SInt32 start; + SInt32 end; + Boolean flag; +} CopyRegion; +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +static CopyRegion *CABI_AppendCopyRegion(CopyRegion *regions, Type *type, SInt32 start, Boolean flag) { + CopyRegion *region; + SInt32 end; + + if (IS_TYPE_BITFIELD(type)) + type = TYPE_BITFIELD(type)->bitfieldtype; + + end = start + type->size; + + if (flag) { + for (region = regions; region; region = region->next) { + if (region->flag) { + if (region->start <= start && region->end >= end) + return regions; + + if (region->start >= start && region->end <= end) { + region->type = type; + region->start = start; + region->end = end; + for (region = region->next; region; region = region->next) { + if (region->start >= start && region->end <= end) + region->end = region->start; + } + return regions; + } + } + } + } + + if (regions) { + region = regions; + while (region->next) + region = region->next; + + region->next = lalloc(sizeof(CopyRegion)); + region = region->next; + } else { + regions = lalloc(sizeof(CopyRegion)); + region = regions; + } + + region->next = NULL; + region->type = type; + region->start = start; + region->end = end; + region->flag = flag; + + return regions; +} + +static ENode *CABI_ClassInitLoopCallBack(ENode *var1, ENode *var2) { + ENodeList *list; + + var2 = makemonadicnode(var2, EINDIRECT); + var2->rtype = TYPE(cabi_loop_class); + + if (cabi_loop_construct) { + list = lalloc(sizeof(ENodeList)); + memclrw(list, sizeof(ENodeList)); + list->node = var2; + return CExpr_ConstructObject(cabi_loop_class, var1, list, 1, 1, 0, 1, 1); + } else { + return CABI_AssignObject(cabi_loop_class, var1, var2); + } +} + +static Statement *CABI_CopyConAssignCB(Statement *stmt, TypeClass *tclass, TypeClass *baseclass, SInt32 offset, Boolean flag) { + ENode *expr; + ENode *expr2; + ENode *startExpr; + ENode *endExpr; + ENodeList *list; + ObjMemberVar *ivar; + CopyRegion *regions; + Type *type; + SInt32 i; + SInt32 count; + Boolean isFlagNotSet; + Object *tmpfunc; + + if (baseclass) { + if (baseclass->flags & CLASS_FLAGS_1000) { + if ( + (flag && !CClass_CopyConstructor(baseclass)) || + (!flag && !CClass_AssignmentOperator(baseclass)) + ) + return stmt; + } + + expr = CABI_MakeCopyConArgExpr(tclass, flag); + expr->rtype = TYPE(baseclass); + expr->data.monadic = CClass_DirectBasePointerCast(expr->data.monadic, tclass, baseclass); + + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + if (flag) { + list = lalloc(sizeof(ENodeList)); + list->next = NULL; + list->node = expr; + + stmt->expr = CExpr_ConstructObject( + baseclass, + CABI_MakeThisExpr(NULL, offset), + list, + 1, 0, 0, 0, 1); + } else { + stmt->expr = CABI_AssignObject( + baseclass, + CClass_DirectBasePointerCast(CABI_MakeThisExpr(NULL, 0), tclass, baseclass), + expr); + } + } else { + isFlagNotSet = !flag; + for (ivar = tclass->ivars, regions = NULL; ivar; ivar = ivar->next) { + if (ivar->name == vptr_name_node) + continue; + + type = ivar->type; + if (isFlagNotSet) { + if (CParser_IsConst(type, ivar->qual) || IS_TYPE_REFERENCE(type) != 0) { + CError_Error(CErrorStr387, tclass, 0); + isFlagNotSet = 0; + } + } + + switch (type->type) { + case TYPEARRAY: + while (IS_TYPE_ARRAY(type)) + type = TPTR_TARGET(type); + if (!IS_TYPE_CLASS(type)) { + regions = CABI_AppendCopyRegion(regions, ivar->type, ivar->offset, 1); + break; + } + case TYPECLASS: + if (flag) { + if (CClass_CopyConstructor(TYPE_CLASS(type)) || CClass_CopyConstructor(TYPE_CLASS(type))) { + regions = CABI_AppendCopyRegion(regions, ivar->type, ivar->offset, 0); + break; + } + } else { + if (CClass_AssignmentOperator(TYPE_CLASS(type))) { + regions = CABI_AppendCopyRegion(regions, ivar->type, ivar->offset, 0); + break; + } + } + default: + regions = CABI_AppendCopyRegion(regions, ivar->type, ivar->offset, 1); + } + } + + for (; regions; regions = regions->next) { + if (regions->start >= regions->end) + continue; + + type = regions->type; + expr = CABI_MakeCopyConArgExpr(tclass, flag); + expr->rtype = type; + + if (!canadd(expr->data.monadic, regions->start)) { + expr->data.monadic = makediadicnode( + expr->data.monadic, + intconstnode(TYPE(&stunsignedlong), regions->start), + EADD); + optimizecomm(expr->data.monadic); + } + + if (!regions->flag) { + if (IS_TYPE_ARRAY(type)) { + while (IS_TYPE_ARRAY(type)) + type = TPTR_TARGET(type); + + CError_ASSERT(1966, IS_TYPE_CLASS(type)); + + if (type->size) { + count = regions->type->size / type->size; + if (count > 4) { + startExpr = CABI_MakeThisExpr(tclass, regions->start); + endExpr = CABI_MakeThisExpr(tclass, regions->start + regions->type->size); + expr = CABI_MakeCopyConArgExpr(tclass, flag)->data.monadic; + if (!canadd(expr, regions->start)) { + expr = makediadicnode( + expr, + intconstnode(TYPE(&stunsignedlong), regions->start), + EADD); + optimizecomm(expr); + } + + cabi_loop_class = TYPE_CLASS(type); + cabi_loop_construct = flag; + stmt = CFunc_GenerateLoop( + stmt, + CDecl_NewPointerType(type), + startExpr, + endExpr, + intconstnode(TYPE(&stunsignedlong), type->size), + expr, + CABI_ClassInitLoopCallBack); + } else { + for (i = 0, offset = regions->start; i < count; offset += type->size, i++) { + expr = CABI_MakeCopyConArgExpr(tclass, flag); + expr->rtype = type; + + if (!canadd(expr->data.monadic, offset)) { + expr->data.monadic = makediadicnode( + expr->data.monadic, + intconstnode(TYPE(&stunsignedlong), offset), + EADD); + optimizecomm(expr->data.monadic); + } + + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + if (flag) { + list = lalloc(sizeof(ENodeList)); + memclrw(list, sizeof(ENodeList)); + list->node = expr; + stmt->expr = CExpr_ConstructObject( + TYPE_CLASS(type), + CABI_MakeThisExpr(tclass, offset), + list, + 1, 1, 0, 1, 1); + } else { + stmt->expr = CABI_AssignObject( + TYPE_CLASS(type), + CABI_MakeThisExpr(tclass, offset), + expr); + } + } + } + + if (flag && (tmpfunc = CClass_Destructor(TYPE_CLASS(type)))) + CExcept_RegisterMemberArray(stmt, CABI_ThisArg(), regions->start, tmpfunc, count, type->size); + } + } else { + CError_ASSERT(2027, IS_TYPE_CLASS(type)); + + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + + if (flag) { + list = lalloc(sizeof(ENodeList)); + memclrw(list, sizeof(ENodeList)); + list->node = expr; + stmt->expr = CExpr_ConstructObject( + TYPE_CLASS(type), + CABI_MakeThisExpr(tclass, regions->start), + list, + 1, 1, 0, 1, 1); + + if ((tmpfunc = CClass_Destructor(TYPE_CLASS(type)))) + CExcept_RegisterMember(stmt, CABI_ThisArg(), regions->start, tmpfunc, NULL, 1); + } else { + stmt->expr = CABI_AssignObject( + TYPE_CLASS(type), + CABI_MakeThisExpr(tclass, regions->start), + expr); + } + } + } else { + if (IS_TYPE_ARRAY(type)) { + if (type->size > 1 && ((regions->start & 1) || (type->size & 1))) { + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + stmt->expr = funccallexpr( + copy_func, + CABI_MakeThisExpr(tclass, regions->start), + getnodeaddress(expr, 0), + intconstnode(CABI_GetSizeTType(), type->size), + NULL); + continue; + } + + type = CDecl_NewStructType(type->size, CMach_GetTypeAlign(type)); + expr->rtype = type; + } + + expr2 = makemonadicnode(CABI_MakeThisExpr(tclass, regions->start), EINDIRECT); + expr2->rtype = type; + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + stmt->expr = makediadicnode(expr2, expr, EASS); + } + } + } + + return stmt; +} + +void CABI_MakeDefaultCopyConstructor(TypeClass *tclass, Object *func) { + Boolean saveDebugInfo; + CScopeSave savedScope; + Statement firstStmt; + Statement returnStmt; + + if (anyerrors || func->access == ACCESSNONE) + return; + + CABI_ApplyClassFlags(func, tclass->eflags, 0); + + CScope_SetFunctionScope(func, &savedScope); + + CFunc_FuncGenSetup(&firstStmt, func); + + saveDebugInfo = copts.isGeneratingDebugInfo; + copts.isGeneratingDebugInfo = 0; + + CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args); + + ctor_chain = NULL; + if (tclass->flags & CLASS_FLAGS_20) + arguments->next->object->name = CParser_GetUniqueName(); + + firstStmt.next = &returnStmt; + + memclrw(&returnStmt, sizeof(Statement)); + returnStmt.type = ST_RETURN; + + CABI_TransConstructor(func, &firstStmt, tclass, CABI_CopyConAssignCB, 0); + + CFunc_CodeCleanup(&firstStmt); + CFunc_Gen(&firstStmt, func, 0); + + CScope_RestoreScope(&savedScope); + copts.isGeneratingDebugInfo = saveDebugInfo; +} + +void CABI_MakeDefaultAssignmentOperator(TypeClass *tclass, Object *func) { + Boolean saveDebugInfo; + Statement *stmt; + ClassList *base; + VClassList *vbase; + ENode *expr1; + ENode *expr2; + CScopeSave savedScope; + Statement firstStmt; + + if (anyerrors || func->access == ACCESSNONE) + return; + + CABI_ApplyClassFlags(func, tclass->eflags, 0); + + CScope_SetFunctionScope(func, &savedScope); + + CFunc_FuncGenSetup(&firstStmt, func); + + saveDebugInfo = copts.isGeneratingDebugInfo; + copts.isGeneratingDebugInfo = 0; + + CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args); + + stmt = curstmt; + + if (tclass->mode == CLASS_MODE_1) { + expr1 = makemonadicnode(CABI_MakeThisExpr(tclass, 0), EINDIRECT); + expr1->rtype = TYPE(tclass); + + expr2 = CABI_MakeCopyConArgExpr(tclass, 0); + expr2->rtype = TYPE(tclass); + + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + stmt->expr = makediadicnode(expr1, expr2, EASS); + } else { + for (vbase = tclass->vbases; vbase; vbase = vbase->next) { + stmt = CABI_CopyConAssignCB(stmt, tclass, vbase->base, vbase->offset, 0); + } + + for (base = tclass->bases; base; base = base->next) { + if (!base->is_virtual) + stmt = CABI_CopyConAssignCB(stmt, tclass, base->base, base->offset, 0); + } + + stmt = CABI_CopyConAssignCB(stmt, tclass, NULL, 0, 0); + } + + stmt = CFunc_InsertStatement(ST_RETURN, stmt); + stmt->expr = CABI_MakeThisExpr(NULL, 0); + + CFunc_CodeCleanup(&firstStmt); + CFunc_Gen(&firstStmt, func, 0); + + CScope_RestoreScope(&savedScope); + copts.isGeneratingDebugInfo = saveDebugInfo; +} + +static Statement *CABI_DestroyMembers(Statement *stmt, ObjMemberVar *ivars, TypeClass *tclass) { + Type *type; + Object *dtor; + ENode *expr; + + for (; ivars; ivars = ivars->next) { + type = ivars->type; + + if (IS_TYPE_ARRAY(type)) { + while (IS_TYPE_ARRAY(type)) + type = TPTR_TARGET(type); + + if (IS_TYPE_CLASS(type) && (dtor = CClass_Destructor(TYPE_CLASS(type)))) { + dtor = CABI_GetDestructorObject(dtor, 1); + stmt = CABI_DestroyMembers(stmt, ivars->next, tclass); + expr = create_objectrefnode(dtor); + expr->flags |= ENODE_FLAG_80; + + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + stmt->expr = funccallexpr( + darr_func, + CABI_MakeThisExpr(tclass, ivars->offset), + expr, + intconstnode(TYPE(&stsignedlong), type->size), + intconstnode(TYPE(&stsignedlong), ivars->type->size / type->size) + ); + return stmt; + } + } else { + if (IS_TYPE_CLASS(type) && (dtor = CClass_Destructor(TYPE_CLASS(type)))) { + stmt = CABI_DestroyMembers(stmt, ivars->next, tclass); + + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + stmt->expr = CABI_DestroyObject( + dtor, + CABI_MakeThisExpr(tclass, ivars->offset), + CABIDestroy1, + 1, + 0 + ); + return stmt; + } + } + } + + return stmt; +} + +static Statement *CABI_DestroyBases(Statement *stmt, ClassList *bases) { + ClassList *base; + Object *dtor; + SInt32 count; + SInt32 i; + + for (base = bases, count = 0; base; base = base->next) + count++; + + while (count > 0) { + base = bases; + for (i = 1; i < count; i++) + base = base->next; + + if (!base->is_virtual && (dtor = CClass_Destructor(base->base))) { + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + stmt->expr = CABI_DestroyObject( + dtor, + CABI_MakeThisExpr(NULL, base->offset), + CABIDestroy0, + 1, + 0); + } + + count--; + } + + return stmt; +} + +static Statement *CABI_DestroyVBases(Statement *stmt, VClassList *vbases) { + Object *dtor; + + for (; vbases; vbases = vbases->next) { + if ((dtor = CClass_Destructor(vbases->base))) { + stmt = CABI_DestroyVBases(stmt, vbases->next); + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + stmt->expr = CABI_DestroyObject( + dtor, + CABI_MakeThisExpr(NULL, vbases->offset), + CABIDestroy0, + 1, + 0); + break; + } + } + + return stmt; +} + +void CABI_TransDestructor(Object *obj1, Object *obj2, Statement *stmt, TypeClass *tclass, CABIDestroyMode mode) { + CLabel *label2; + Boolean flag29; + CLabel *label; + Statement *scan; + Boolean flag25; + Boolean flag24; + Boolean flag23; + CLabel *label3; + Object *dealloc; + Boolean deallocFlag; + + if (tclass->sominfo) { + flag24 = 0; + flag25 = 0; + flag29 = 0; + flag23 = 1; + } else { + flag24 = 1; + flag23 = 1; + flag25 = 1; + flag29 = 1; + } + + label = newlabel(); + + for (scan = stmt; scan; scan = scan->next) { + if (scan->type == ST_RETURN) { + CError_ASSERT(2329, !scan->expr); + scan->type = ST_GOTO; + scan->label = label; + } + + if (scan->next && scan->next->type == ST_RETURN && !scan->next->next) { + CError_ASSERT(2334, !scan->next->expr); + scan->next = NULL; + break; + } + } + + scan = stmt; + + if (flag29) { + label2 = newlabel(); + scan = CFunc_InsertStatement(ST_IFNGOTO, scan); + scan->expr = CABI_MakeThisExpr(NULL, 0); + scan->label = label2; + } + + if (flag25 && tclass->vtable && tclass->vtable->object && tclass->vtable->owner == tclass) { + cabi_pathroot.next = NULL; + cabi_pathroot.type = TYPE(tclass); + cabi_pathcur = &cabi_pathroot; + trans_vtboffsets = NULL; + scan = CABI_InitVTablePtrs(scan, tclass->vtable->object, tclass, tclass, 0, 0); + } + + if (!tclass->sominfo && (tclass->flags & CLASS_FLAGS_8000)) + CABI_InitVBaseCtorOffsets(scan, tclass); + + scan = stmt; + while (scan->next) + scan = scan->next; + + scan = CFunc_InsertStatement(ST_LABEL, scan); + scan->label = label; + scan->dobjstack = NULL; + label->stmt = scan; + + if (flag23 && !(tclass->flags & CLASS_FLAGS_1)) + scan = CABI_DestroyMembers(scan, tclass->ivars, tclass); + + if (flag25 && tclass->bases) + scan = CABI_DestroyBases(scan, tclass->bases); + + if (flag24 && (tclass->flags & CLASS_FLAGS_20)) { + label3 = newlabel(); + scan = CFunc_InsertStatement(ST_IFNGOTO, scan); + scan->expr = CABI_MakeVArgExpr(); + scan->label = label3; + + scan = CABI_DestroyVBases(scan, tclass->vbases); + + scan = CFunc_InsertStatement(ST_LABEL, scan); + scan->label = label3; + label3->stmt = scan; + } + + if (flag29) { + scan = CFunc_InsertStatement(ST_IFGOTO, scan); + scan->expr = CExpr_New_ELESSEQU_Node(CABI_MakeVArgExpr(), intconstnode(TYPE(&stsignedshort), 0)); + scan->label = label2; + + scan = CFunc_InsertStatement(ST_EXPRESSION, scan); + dealloc = CParser_FindDeallocationObject(TYPE(tclass), NULL, 0, 0, &deallocFlag); + if (deallocFlag) { + scan->expr = funccallexpr( + dealloc, + CABI_MakeThisExpr(NULL, 0), + intconstnode(CABI_GetSizeTType(), tclass->size), + NULL, + NULL); + } else { + scan->expr = funccallexpr(dealloc, CABI_MakeThisExpr(NULL, 0), NULL, NULL, NULL); + } + + scan = CFunc_InsertStatement(ST_LABEL, scan); + scan->label = label2; + label2->stmt = scan; + } + + scan = CFunc_InsertStatement(ST_RETURN, scan); + if (tclass->sominfo) + scan->expr = NULL; + else + scan->expr = CABI_MakeThisExpr(NULL, 0); +} + +void CABI_MakeDefaultDestructor(TypeClass *tclass, Object *func) { + Boolean saveDebugInfo; + CScopeSave savedScope; + Statement firstStmt; + Statement returnStmt; + + if (anyerrors || func->access == ACCESSNONE) + return; + + CABI_ApplyClassFlags(func, tclass->eflags, 0); + + CScope_SetFunctionScope(func, &savedScope); + + CFunc_FuncGenSetup(&firstStmt, func); + + saveDebugInfo = copts.isGeneratingDebugInfo; + copts.isGeneratingDebugInfo = 0; + + CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args); + + firstStmt.next = &returnStmt; + + memclrw(&returnStmt, sizeof(Statement)); + returnStmt.type = ST_RETURN; + + CFunc_CodeCleanup(&firstStmt); + + CABI_TransDestructor(func, func, &firstStmt, tclass, CABIDestroy0); + + CFunc_Gen(&firstStmt, func, 0); + + CScope_RestoreScope(&savedScope); + copts.isGeneratingDebugInfo = saveDebugInfo; +} + +static void CABI_CreateLayeredDestructor(TypeClass *tclass, Object *obj1, Object *func, CABIDestroyMode mode) { + Boolean saveDebugInfo; + CScopeSave savedScope; + Statement firstStmt; + Statement returnStmt; + + CError_FATAL(2524); + + CScope_SetFunctionScope(func, &savedScope); + + CFunc_FuncGenSetup(&firstStmt, func); + + saveDebugInfo = copts.isGeneratingDebugInfo; + copts.isGeneratingDebugInfo = 0; + + CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args); + + firstStmt.next = &returnStmt; + + memclrw(&returnStmt, sizeof(Statement)); + returnStmt.type = ST_RETURN; + + CFunc_CodeCleanup(&firstStmt); + + CABI_TransDestructor(obj1, func, &firstStmt, tclass, mode); + + CFunc_Gen(&firstStmt, func, 0); + + CScope_RestoreScope(&savedScope); + copts.isGeneratingDebugInfo = saveDebugInfo; +} + +void CABI_MakeLayeredDestructor(TypeClass *tclass, Object *func) { + Object *dtor; + CABIDestroyMode mode; + + CError_FATAL(2557); + + if (anyerrors || func->access == ACCESSNONE) + return; + + if ((dtor = CClass_Destructor(tclass))) { + if (CABI_GetDestructorObject(dtor, CABIDestroy0) == func) + mode = CABIDestroy0; + else if (CABI_GetDestructorObject(dtor, CABIDestroy2) == func) + mode = CABIDestroy2; + else if (CABI_GetDestructorObject(dtor, CABIDestroy3) == func) + mode = CABIDestroy3; + else if (CABI_GetDestructorObject(dtor, CABIDestroy1) == func) + mode = CABIDestroy1; + else + CError_FATAL(2567); + } + + CABI_CreateLayeredDestructor(tclass, dtor, func, mode); +} + +Object *CABI_GetDestructorObject(Object *obj, CABIDestroyMode mode) { return obj; } -static void CABI_AddLayeredDestructor() {} -void CABI_AddLayeredDestructors(TypeClass *tclass) {} +static void CABI_AddLayeredDestructor(TypeClass *tclass, Object *dtor, HashNameNode *name, Boolean is_virtual) { + Object *func; + + CError_FATAL(2667); + + func = CParser_NewFunctionObject(NULL); + func->nspace = dtor->nspace; + func->name = name; + func->type = TYPE(CDecl_MakeDefaultDtorType(tclass, is_virtual)); + func->qual = Q_20000 | Q_80000; + func->qual |= Q_INLINE; + CABI_ApplyClassFlags(func, tclass->eflags, 1); + + CError_ASSERT(2678, IS_TYPE_FUNC(func->type)); + TYPE_FUNC(func->type)->flags |= FUNC_FLAGS_100; + + if (dtor->datatype == DVFUNC) { + func->datatype = DVFUNC; + CMangler_GetLinkName(func); + func->datatype = DFUNC; + } -ENode *CABI_DestroyObject(Object *dtor, ENode *objexpr, UInt8 mode, Boolean flag1, Boolean flag2) {} + CScope_AddObject(func->nspace, func->name, OBJ_BASE(func)); +} + +void CABI_AddLayeredDestructors(TypeClass *tclass) { + Object *dtor; + + CError_FATAL(2707); + + if ((dtor = CClass_Destructor(tclass))) { + CABI_AddLayeredDestructor(tclass, dtor, CMangler_DeleteDtorName(), 1); + CABI_AddLayeredDestructor(tclass, dtor, CMangler_SDeleteDtorName(), 1); + if (tclass->vbases) + CABI_AddLayeredDestructor(tclass, dtor, CMangler_VBaseDtorName(), 0); + } +} + +ENode *CABI_DestroyObject(Object *dtor, ENode *objexpr, CABIDestroyMode mode, Boolean flag1, Boolean flag2) { + ENode *expr; + short arg; + ENodeList *list; + + switch (mode) { + case CABIDestroy2: + case CABIDestroy3: + if (flag2) + arg = 1; + else + arg = -1; + break; + case CABIDestroy1: + arg = -1; + break; + case CABIDestroy0: + arg = 0; + break; + default: + CError_FATAL(2786); + } + + expr = lalloc(sizeof(ENode)); + expr->type = EFUNCCALL; + expr->cost = 200; + expr->flags = 0; + expr->rtype = &stvoid; + expr->data.funccall.funcref = create_objectrefnode(dtor); + if (flag1) + expr->data.funccall.funcref->flags |= ENODE_FLAG_80; + expr->data.funccall.functype = TYPE_FUNC(dtor->type); + dtor->flags |= OBJECT_FLAGS_UNUSED; + + list = lalloc(sizeof(ENodeList)); + list->node = objexpr; + expr->data.funccall.args = list; + + list->next = lalloc(sizeof(ENodeList)); + list = list->next; + list->next = NULL; + list->node = intconstnode(TYPE(&stsignedshort), arg); + + return expr; +} diff --git a/compiler_and_linker/unsorted/CClass.c b/compiler_and_linker/unsorted/CClass.c index 0d2091b..961d99b 100644 --- a/compiler_and_linker/unsorted/CClass.c +++ b/compiler_and_linker/unsorted/CClass.c @@ -1,12 +1,24 @@ #include "compiler/CClass.h" +#include "compiler/CABI.h" +#include "compiler/CDecl.h" #include "compiler/CError.h" +#include "compiler/CExpr.h" +#include "compiler/CInit.h" #include "compiler/CInline.h" +#include "compiler/CMachine.h" #include "compiler/CMangler.h" +#include "compiler/CObjC.h" #include "compiler/CParser.h" +#include "compiler/CRTTI.h" +#include "compiler/CSOM.h" #include "compiler/CompilerTools.h" #include "compiler/CodeGen.h" #include "compiler/objects.h" +#include "compiler/scopes.h" +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif typedef struct OVClassBase { struct OVClassBase *next; struct OVClass *ovclass; @@ -38,16 +50,19 @@ typedef struct ThunkList { SInt32 b; SInt32 c; } ThunkList; +#ifdef __MWERKS__ +#pragma options align=reset +#endif static TypeClass *main_class; static ThunkList *cclass_thunklist; static TypeClass *cclass_isbase_mostderived; -static void *cclass_isbase_foundoffset; // TODO type +static SInt32 cclass_isbase_foundoffset; static Boolean cclass_isambigbase; static short cclass_founddepth; -static void *vtable_object_data; // TODO type -static void *vtable_data_size; // TODO type -static VTableObjectLink *vtable_object_links; +static char *vtable_object_data; +static SInt32 vtable_data_size; +static OLinkList *vtable_object_links; static TypeClass *cclass_vbase; static OVClass *cclass_ovbase; static OVClass *cclass_root; @@ -60,13 +75,15 @@ static TypeClass *cclass_dominator_oclass; static SInt32 cclass_dominator_ooffset; static Object *cclass_dominator_eobject; -void CClass_Init(void) {} +void CClass_Init(void) { + cclass_thunklist = NULL; +} void CClass_GenThunks(void) { ThunkList *list; for (list = cclass_thunklist; list; list = list->next) { - list->obj->flags |= OBJECT_FLAGS_4; + list->thunkobj->flags |= OBJECT_FLAGS_4; CodeGen_GenVDispatchThunk(list->thunkobj, list->obj, list->a, list->b, list->c); } } @@ -100,76 +117,2196 @@ static Object *CClass_ThunkObject(Object *obj, SInt32 a, SInt32 b, SInt32 c) { return thunkobj; } -static Boolean CClass_IsZeroOffsetClass(TypeClass *a, TypeClass *b) {} -static UInt8 CClass_IsCovariantResult(Type *a, UInt32 qualA, Type *b, UInt32 qualB) {} -UInt8 CClass_GetOverrideKind(TypeFunc *a, TypeFunc *b, Boolean errorflag) {} -Boolean CClass_IsEmpty(TypeClass *tclass) {} -Boolean CClass_IsNonStaticMemberFunc(TypeMethod *tmethod) {} -Object *CClass_DefaultConstructor(TypeClass *tclass) {} -Object *CClass_DummyDefaultConstructor(TypeClass *tclass) {} -ENode *CClass_DefaultConstructorCall(TypeClass *a, TypeClass *b, ENode *expr, SInt32 unkshortparam, Boolean flag1, Boolean flag2, Boolean *errorflag) {} -Object *CClass_AssignmentOperator(TypeClass *tclass) {} -Object *CClass_CopyConstructor(TypeClass *tclass) {} -NameSpaceObjectList *CClass_MemberObject(TypeClass *tclass, HashNameNode *name) {} -NameSpaceObjectList *CClass_Constructor(TypeClass *tclass) {} -Object *CClass_Destructor(TypeClass *tclass) {} -Boolean CClass_IsConstructor(Object *obj) {} -Boolean CClass_IsDestructor(Object *obj) {} -Boolean CClass_IsPODClass(TypeClass *tclass) {} -Boolean CClass_IsTrivialCopyClass(TypeClass *tclass) {} -Boolean CClass_IsTrivialCopyAssignClass(TypeClass *tclass) {} -Boolean CClass_ReferenceArgument(TypeClass *tclass) {} -BClassList *CClass_GetPathCopy(BClassList *path, Boolean is_global) {} -BClassList *CClass_AppendPath(BClassList *a, BClassList *b) {} -static AccessType CClass_GetPathAccess(BClassList *path) {} -Boolean CClass_IsMoreAccessiblePath(BClassList *path1, BClassList *path2) {} -static BClassList *CClass_GetBasePathRec(TypeClass *a, TypeClass *b, SInt32 offset, short depth) {} -BClassList *CClass_GetBasePath(TypeClass *a, TypeClass *b, short *founddepth, Boolean *isambigbase) {} -Boolean CClass_IsBaseClass(TypeClass *a, TypeClass *b, short *founddepth, Boolean pathcheckflag, Boolean ambigerrorflag) {} -TypeClass *CClass_GetQualifiedClass(void) {} -ENode *CClass_AccessPathCast(BClassList *path, ENode *expr, Boolean flag) {} -ENode *CClass_ClassPointerCast(ENode *expr, TypeClass *a, TypeClass *b, Boolean typconflag, Boolean ambigerrorflag, Boolean pathcheckflag) {} -ENode *CClass_DirectBasePointerCast(ENode *expr, TypeClass *a, TypeClass *b) {} -SInt32 CClass_GetPathOffset(BClassList *path) {} -Boolean CClass_ClassDominates(TypeClass *a, TypeClass *b) {} -SInt32 CClass_VirtualBaseOffset(TypeClass *a, TypeClass *b) {} -SInt32 CClass_VirtualBaseVTableOffset(TypeClass *a, TypeClass *b) {} -SInt32 CClass_GetMemberOffset(TypeClass *tclass, HashNameNode *name, ObjMemberVar **obj) {} -Boolean CClass_OverridesBaseMember(TypeClass *tclass, HashNameNode *name, Object *obj) {} -static OVClass *CClass_FindOVClass(OVClass *ovclass, TypeClass *tclass, SInt32 offset) {} -static OVClass *CClass_BuildOVClassTree(OVClass *root, TypeClass *tclass, SInt32 offset, SInt32 voffset) {} -static Boolean CClass_IsBaseOf(OVClass *a, OVClass *b) {} -static void CClass_FindOVFunc(OVClass *a, OVClass *b, OVFunc *func) {} -static TypeList *CClass_GetCoVariantClassList(TypeList *list, TypeClass *tclass, Object *func, Boolean flag) {} -static TypeMethod *CClass_GetCovariantType(TypeMethod *tmethod, Type *type) {} -static Object *CClass_FindCovariantFunction(Object *func, Type *type) {} -static ObjectList *CClass_DeclareCovariantFuncs(ObjectList *list, Object *func, TypeClass *tclass) {} -void CClass_DefineCovariantFuncs(Object *method, CI_FuncData *ifuncdata) {} -static void CClass_OverrideOVClassTree(OVClass *ovclass) {} -static void CClass_AllocVTableRec(OVClass *ovclass) {} -static Object *CClass_CheckClass(OVClass *ovclass, Boolean errorflag) {} -static void CClass_AllocVTable(TypeClass *tclass) {} -static Object *CClass_CheckVirtuals(TypeClass *tclass) {} -static void CClass_CheckVirtualBaseOverrides(OVClass *a, OVClass *b, Boolean flag) {} -static void CClass_CheckHideVirtual(OVClass *a, OVClass *b) {} -void CClass_CheckOverrides(TypeClass *tclass) {} -static void CClass_FindDominator(TypeClass *tclass1, SInt32 offset1, Object *object1, TypeClass *tclass2, SInt32 offset2, TypeClass *base) {} -static void CClass_ConstructVTable(TypeClass *tclass, SInt32 voffset, SInt32 offset, TypeClass *base) {} -void CClass_ClassDefaultFuncAction(TypeClass *tclass) {} -void CClass_ClassAction(TypeClass *tclass) {} -void CClass_MakeStaticActionClass(TypeClass *tclass) {} -Object *CClass_CheckPures(TypeClass *tclass) {} -void CClass_MemberDef(Object *obj, TypeClass *tclass) {} -Object *CClass_ThisSelfObject(void) {} -ENode *CClass_CreateThisSelfExpr(void) {} -static Boolean CClass_BaseMemberAccess(BClassList *path, AccessType access) {} -static Boolean CClass_CanAccess(BClassList *path, AccessType access) {} -void CClass_CheckPathAccess(BClassList *path, Object *obj, AccessType access) {} -static BClassList *CClass_PathCleanup(BClassList *path, TypeClass *tclass) {} -void CClass_CheckStaticAccess(BClassList *path, TypeClass *tclass, AccessType access) {} -void CClass_CheckObjectAccess(BClassList *path, Object *obj) {} -void CClass_CheckEnumAccess(BClassList *path, ObjEnumConst *objec) {} -static Type *CClass_PointerTypeCopy(Type *type) {} -Type *CClass_CombineClassAccessQualifiers(Type *type, UInt32 qual1, UInt32 qual2, UInt32 *outflags) {} -static void CClass_OptimizeBitFieldAccess(Type **type, SInt32 *offset) {} -ENode *CClass_AccessMember(ENode *classexpr, Type *type, UInt32 qual, SInt32 offset) {} +static Boolean CClass_IsZeroOffsetClass(TypeClass *a, TypeClass *b) { + while (1) { + if (a == b) + return 1; + + if (!a->bases || a->bases->is_virtual) + return 0; + + a = a->bases->base; + } +} + +static UInt8 CClass_IsCovariantResult(Type *a, UInt32 qualA, Type *b, UInt32 qualB, Boolean errorflag) { + TypeClass *tclassA; + TypeClass *tclassB; + + if ( + IS_TYPE_POINTER_ONLY(a) && + IS_TYPE_POINTER_ONLY(b) && + TPTR_QUAL(a) == TPTR_QUAL(b) && + !CParser_IsMoreCVQualified(qualB, qualA) && + IS_TYPE_CLASS(TPTR_TARGET(a)) && + IS_TYPE_CLASS(TPTR_TARGET(b)) + ) + { + tclassA = TYPE_CLASS(TPTR_TARGET(a)); + tclassB = TYPE_CLASS(TPTR_TARGET(b)); + if (tclassA == tclassB || CClass_IsBaseClass(tclassB, tclassA, NULL, errorflag, errorflag)) { + if (!CClass_IsZeroOffsetClass(tclassB, tclassA)) + return 2; + else + return 1; + } + } + + return 0; +} + +UInt8 CClass_GetOverrideKind(TypeFunc *a, TypeFunc *b, Boolean errorflag) { + if (!a->args || !b->args) + return 0; + + if ( + (a->flags & (FUNC_FLAGS_PASCAL | FUNC_FLAGS_F0000000)) != (b->flags & (FUNC_FLAGS_PASCAL | FUNC_FLAGS_F0000000)) || + !is_arglistsame(a->args->next, b->args->next) || + a->args->qual != b->args->qual + ) + return 0; + + if (!is_typesame(a->functype, b->functype)) { + switch (CClass_IsCovariantResult(a->functype, a->qual, b->functype, b->qual, errorflag)) { + case 0: + if (errorflag) + CError_Error(CErrorStr227); + return 0; + case 1: + return 1; + case 2: + return 2; + default: + CError_FATAL(225); + } + } + + return 1; +} + +Boolean CClass_IsEmpty(TypeClass *tclass) { + ClassList *base; + + if (tclass->ivars) + return 0; + + for (base = tclass->bases; base; base = base->next) { + if (!CClass_IsEmpty(base->base)) + return 0; + } + + return 1; +} + +Boolean CClass_IsNonStaticMemberFunc(TypeFunc *tfunc) { + return IS_TYPEFUNC_NONSTATIC_METHOD(tfunc) || (tfunc->flags & FUNC_FLAGS_80); +} + +Object *CClass_DefaultConstructor(TypeClass *tclass) { + NameSpaceObjectList *nsol; + Object *object; + + for (nsol = CScope_FindName(tclass->nspace, constructor_name_node); nsol; nsol = nsol->next) { + object = OBJECT(nsol->object); + if (object->otype == OT_OBJECT && IS_TYPE_FUNC(object->type)) { + if ((tclass->flags & CLASS_FLAGS_20) && !tclass->sominfo) { + if (TYPE_FUNC(object->type)->args->next && !TYPE_FUNC(object->type)->args->next->next) + return object; + } else { + if (!TYPE_FUNC(object->type)->args->next) + return object; + } + } + } + + return NULL; +} + +Object *CClass_DummyDefaultConstructor(TypeClass *tclass) { + Object *ctor; + FuncArg *args; + NameSpaceObjectList *nsol; + HashNameNode *name; + TypeMethod *tmethod; + Object *object; + ObjectList list; + + ctor = NULL; + + for (nsol = CScope_FindName(tclass->nspace, constructor_name_node); nsol; nsol = nsol->next) { + object = OBJECT(nsol->object); + if (object->otype == OT_OBJECT && IS_TYPE_FUNC(object->type)) { + CError_ASSERT(305, args = TYPE_FUNC(object->type)->args); + args = args->next; + if ((tclass->flags & CLASS_FLAGS_20) && !tclass->sominfo) { + CError_ASSERT(309, args); + args = args->next; + } + CError_ASSERT(312, args); + + if (args->dexpr) { + if (ctor) { + list.next = NULL; + list.object = object; + CError_OverloadedFunctionError(ctor, &list); + break; + } + ctor = object; + } + } + } + + if (!ctor) { + CError_Error(CErrorStr203); + return NULL; + } + + name = GetHashNameNodeExport("__defctor"); + if ((nsol = CScope_FindName(tclass->nspace, name))) { + CError_ASSERT(339, nsol->object->otype == OT_OBJECT && IS_TYPE_FUNC(OBJECT(nsol->object)->type)); + return OBJECT(nsol->object); + } + + tmethod = galloc(sizeof(TypeMethod)); + memclrw(tmethod, sizeof(TypeMethod)); + + tmethod->type = TYPEFUNC; + tmethod->functype = TYPE(&void_ptr); + tmethod->flags = FUNC_FLAGS_METHOD; + tmethod->theclass = tclass; + CDecl_SetFuncFlags(TYPE_FUNC(tmethod), 0); + + if ((tclass->flags & CLASS_FLAGS_20) && !tclass->sominfo) + CDecl_AddArgument(TYPE_FUNC(tmethod), TYPE(&stsignedshort)); + + CDecl_AddThisPointerArgument(TYPE_FUNC(tmethod), tclass); + + object = CParser_NewCompilerDefFunctionObject(); + object->type = TYPE(tmethod); + object->qual = Q_INLINE | Q_80000; + object->nspace = tclass->nspace; + object->name = name; + + CScope_AddObject(tclass->nspace, name, OBJ_BASE(object)); + CParser_RegisterDummyCtorFunction(object, ctor); + return object; +} + +ENode *CClass_DefaultConstructorCall(TypeClass *tclass, TypeClass *b, ENode *objexpr, SInt32 varg, Boolean flag1, Boolean flag2, Boolean *errorflag) { + NameSpaceObjectList *nsol; + Object *ctor; + Object *object; + FuncArg *args; + ENodeList *argexprs; + ENode *expr; + BClassList *path; + BClassList list1; + ObjectList objlist; + BClassList list2; + short founddepth; + Boolean isambigbase; + + *errorflag = 0; + + if (!(nsol = CScope_FindName(tclass->nspace, constructor_name_node))) + return NULL; + + ctor = NULL; + do { + object = OBJECT(nsol->object); + if (object->otype == OT_OBJECT && IS_TYPE_FUNC(object->type)) { + CError_ASSERT(397, args = TYPE_FUNC(object->type)->args); + + args = args->next; + + if ((tclass->flags & CLASS_FLAGS_20) && !tclass->sominfo) { + CError_ASSERT(401, args); + args = args->next; + } + + if (!args || args->dexpr) { + if (ctor) { + objlist.next = NULL; + objlist.object = object; + CError_OverloadedFunctionError(ctor, &objlist); + break; + } + ctor = object; + } + } + } while ((nsol = nsol->next)); + + if (!ctor) { + *errorflag = 1; + return NULL; + } + + if (flag1) { + if (b) { + if (flag2) { + if ((path = CClass_GetBasePath(b, tclass, &founddepth, &isambigbase))) + list1 = *path; + else + goto skipCheck; + } else { + list1.next = &list2; + list1.type = TYPE(b); + list2.next = NULL; + list2.type = TYPE(tclass); + } + } else { + list1.next = NULL; + list1.type = TYPE(tclass); + } + CClass_CheckPathAccess(&list1, ctor, ctor->access); + } + +skipCheck: + if ((tclass->flags & CLASS_FLAGS_20) && !tclass->sominfo) { + argexprs = lalloc(sizeof(ENodeList)); + argexprs->next = NULL; + argexprs->node = intconstnode(TYPE(&stsignedshort), varg); + } else { + argexprs = NULL; + } + + CError_ASSERT(471, IS_TYPE_POINTER_ONLY(objexpr->rtype)); + + objexpr = makemonadicnode(objexpr, EINDIRECT); + objexpr->rtype = TYPE(tclass); + + list1.next = NULL; + list1.type = TYPE(tclass); + + expr = CExpr_GenericFuncCall( + &list1, + objexpr, + 0, + ctor, + NULL, + NULL, + argexprs, + 0, + 0, + 0 + ); + + if (ENODE_IS2(expr, EFUNCCALL, EFUNCCALLP)) + expr->rtype = CDecl_NewPointerType(TYPE(tclass)); + + return expr; +} + +Object *CClass_AssignmentOperator(TypeClass *tclass) { + NameSpaceObjectList *nsol; + Object *object; + + for (nsol = CScope_FindName(tclass->nspace, asop_name_node); nsol; nsol = nsol->next) { + object = OBJECT(nsol->object); + if ( + object->otype == OT_OBJECT && + IS_TYPE_FUNC(object->type) && + TYPE_FUNC(object->type)->args && + TYPE_FUNC(object->type)->args->next && + !TYPE_FUNC(object->type)->args->next->next + ) + { + if ( + IS_TYPE_CLASS(TYPE_FUNC(object->type)->args->next->type) && + TYPE_CLASS(TYPE_FUNC(object->type)->args->next->type) == tclass + ) + return object; + + if ( + IS_TYPE_REFERENCE(TYPE_FUNC(object->type)->args->next->type) && + TPTR_TARGET(TYPE_FUNC(object->type)->args->next->type) == TYPE(tclass) + ) + return object; + } + } + + return NULL; +} + +Object *CClass_CopyConstructor(TypeClass *tclass) { + NameSpaceObjectList *nsol; + Object *object; + FuncArg *args; + + if (tclass->sominfo) + return NULL; + + for (nsol = CScope_FindName(tclass->nspace, constructor_name_node); nsol; nsol = nsol->next) { + object = OBJECT(nsol->object); + if (object->otype == OT_OBJECT && IS_TYPE_FUNC(object->type)) { + CError_ASSERT(532, args = TYPE_FUNC(object->type)->args); + + args = args->next; + + if (tclass->flags & CLASS_FLAGS_20) { + CError_ASSERT(536, args); + args = args->next; + } + + if ( + args && + args != &elipsis && + (!args->next || args->next->dexpr) && + IS_TYPE_REFERENCE(args->type) && + TPTR_TARGET(args->type) == TYPE(tclass) + ) + return object; + } + } + + return NULL; +} + +NameSpaceObjectList *CClass_MemberObject(TypeClass *tclass, HashNameNode *name) { + NameSpaceObjectList *nsol; + + if ((nsol = CScope_FindName(tclass->nspace, name)) && nsol->object->otype == OT_OBJECT) + return nsol; + + return NULL; +} + +NameSpaceObjectList *CClass_Constructor(TypeClass *tclass) { + NameSpaceObjectList *nsol; + + if ( + (nsol = CScope_FindName(tclass->nspace, constructor_name_node)) && + nsol->object->otype == OT_OBJECT && + IS_TYPE_FUNC(OBJECT(nsol->object)->type) + ) + return nsol; + + return NULL; +} + +Object *CClass_Destructor(TypeClass *tclass) { + NameSpaceObjectList *nsol; + + for (nsol = CScope_FindName(tclass->nspace, destructor_name_node); nsol; nsol = nsol->next) { + if ( + nsol->object->otype == OT_OBJECT && + IS_TYPE_FUNC(OBJECT(nsol->object)->type) + ) + return OBJECT(nsol->object); + } + + return NULL; +} + +Boolean CClass_IsConstructor(Object *obj) { + return obj && IS_TYPE_FUNC(obj->type) && (TYPE_FUNC(obj->type)->flags & FUNC_FLAGS_1000); +} + +Boolean CClass_IsDestructor(Object *obj) { + return obj && IS_TYPE_FUNC(obj->type) && (TYPE_FUNC(obj->type)->flags & FUNC_FLAGS_2000); +} + +Boolean CClass_IsPODClass(TypeClass *tclass) { + NameSpaceObjectList *nsol; + Object *object; + ObjMemberVar *ivar; + Type *type; + + if (tclass->vtable || tclass->bases || CClass_Destructor(tclass)) + return 0; + + for (nsol = CClass_Constructor(tclass); nsol; nsol = nsol->next) { + if ( + nsol->object->otype == OT_OBJECT && + IS_TYPE_FUNC(OBJECT(nsol->object)->type) && + !(TYPE_FUNC(OBJECT(nsol->object)->type)->flags & FUNC_FLAGS_100) + ) + return 0; + } + + object = CClass_AssignmentOperator(tclass); + if (object && !(TYPE_FUNC(object->type)->flags & FUNC_FLAGS_100)) + return 0; + + for (ivar = tclass->ivars; ivar; ivar = ivar->next) { + if (ivar->access != ACCESSPUBLIC) + return 0; + + type = ivar->type; + while (IS_TYPE_ARRAY(type)) + type = TPTR_TARGET(type); + + switch (type->type) { + case TYPECLASS: + if (!CClass_IsPODClass(TYPE_CLASS(type))) + return 0; + break; + case TYPEMEMBERPOINTER: + return 0; + case TYPEPOINTER: + if (TPTR_QUAL(type) & Q_REFERENCE) + return 0; + break; + } + } + + return 1; +} + +Boolean CClass_IsTrivialCopyClass(TypeClass *tclass) { + Object *object; + ClassList *base; + ObjMemberVar *ivar; + Type *type; + + if (tclass->vtable || tclass->vbases || CClass_Destructor(tclass)) + return 0; + + object = CClass_CopyConstructor(tclass); + if (object && IS_TYPE_FUNC(object->type) && !(TYPE_FUNC(object->type)->flags & FUNC_FLAGS_100)) + return 0; + + for (base = tclass->bases; base; base = base->next) { + if (!CClass_IsTrivialCopyClass(base->base)) + return 0; + } + + for (ivar = tclass->ivars; ivar; ivar = ivar->next) { + type = ivar->type; + while (IS_TYPE_ARRAY(type)) + type = TPTR_TARGET(type); + + if (IS_TYPE_CLASS(type) && !CClass_IsTrivialCopyClass(TYPE_CLASS(type))) + return 0; + } + + return 1; +} + +Boolean CClass_IsTrivialCopyAssignClass(TypeClass *tclass) { + Object *object; + ObjMemberVar *ivar; + Type *type; + + if (tclass->vtable || tclass->bases || CClass_Destructor(tclass)) + return 0; + + object = CClass_AssignmentOperator(tclass); + if (object && !(TYPE_FUNC(object->type)->flags & FUNC_FLAGS_100)) + return 0; + + for (ivar = tclass->ivars; ivar; ivar = ivar->next) { + type = ivar->type; + while (IS_TYPE_ARRAY(type)) + type = TPTR_TARGET(type); + + if (IS_TYPE_REFERENCE(type)) + return 0; + if (CParser_IsConst(type, ivar->qual)) + return 0; + if (IS_TYPE_CLASS(type) && !CClass_IsTrivialCopyAssignClass(TYPE_CLASS(type))) + return 0; + } + + return 1; +} + +Boolean CClass_ReferenceArgument(TypeClass *tclass) { + if ((tclass->flags & (CLASS_FLAGS_2 | CLASS_FLAGS_800)) == CLASS_FLAGS_800) + CDecl_CompleteType(TYPE(tclass)); + + if (copts.simple_class_byval) + return !CClass_IsTrivialCopyClass(tclass); + + return CClass_Destructor(tclass) || CClass_CopyConstructor(tclass); +} + +BClassList *CClass_GetPathCopy(BClassList *path, Boolean is_global) { + BClassList *last; + BClassList *copy; + + if (!path) + return NULL; + + copy = last = is_global ? galloc(sizeof(BClassList)) : lalloc(sizeof(BClassList)); + last->next = path->next; + last->type = path->type; + + while ((path = path->next)) { + last->next = is_global ? galloc(sizeof(BClassList)) : lalloc(sizeof(BClassList)); + last = last->next; + last->next = path->next; + last->type = path->type; + } + + return copy; +} + +BClassList *CClass_AppendPath(BClassList *dest, BClassList *src) { + BClassList *last; + + if (!(last = dest)) + return src; + + while (last->next) + last = last->next; + + while (src && src->type == last->type) + src = src->next; + + last->next = src; + return dest; +} + +static AccessType CClass_GetPathAccess(BClassList *path) { + AccessType result; + ClassList *base; + TypeClass *tclass; + + CError_ASSERT(930, path); + + result = ACCESSPUBLIC; + + while (1) { + tclass = TYPE_CLASS(path->type); + if (!(path = path->next)) + break; + + for (base = tclass->bases; base; base = base->next) { + if (base->base == TYPE_CLASS(path->type)) + break; + } + + CError_ASSERT(939, base); + + switch (base->access) { + case ACCESSPUBLIC: + break; + case ACCESSPROTECTED: + if (result == ACCESSPUBLIC) + result = ACCESSPROTECTED; + break; + case ACCESSPRIVATE: + if (result == ACCESSPUBLIC || result == ACCESSPROTECTED) + result = ACCESSPRIVATE; + else + return ACCESSNONE; + break; + case ACCESSNONE: + return ACCESSNONE; + default: + CError_FATAL(960); + } + } + + return result; +} + +Boolean CClass_IsMoreAccessiblePath(BClassList *path1, BClassList *path2) { + switch (CClass_GetPathAccess(path2)) { + case ACCESSPUBLIC: + return 0; + case ACCESSNONE: + return 1; + default: + CError_FATAL(978); + case ACCESSPROTECTED: + switch (CClass_GetPathAccess(path1)) { + case ACCESSPUBLIC: + return 1; + case ACCESSPRIVATE: + case ACCESSPROTECTED: + case ACCESSNONE: + return 0; + default: + CError_FATAL(987); + } + case ACCESSPRIVATE: + switch (CClass_GetPathAccess(path1)) { + case ACCESSPUBLIC: + case ACCESSPROTECTED: + return 1; + case ACCESSPRIVATE: + case ACCESSNONE: + return 0; + default: + CError_FATAL(997); + } + } + + return 0; +} + +static BClassList *CClass_GetBasePathRec(TypeClass *a, TypeClass *b, SInt32 offset, short depth) { + ClassList *base; + BClassList *checkpath; + BClassList *bestpath; + BClassList *newpath; + SInt32 newOffset; + + for (base = a->bases, bestpath = NULL; base; base = base->next) { + if (base->is_virtual) + newOffset = CClass_VirtualBaseOffset(cclass_isbase_mostderived, base->base); + else + newOffset = offset + base->offset; + + if (base->base == b) { + if (cclass_founddepth && newOffset != cclass_isbase_foundoffset) { + cclass_isambigbase = 1; + return NULL; + } + + cclass_isbase_foundoffset = newOffset; + cclass_founddepth = depth; + + bestpath = lalloc(sizeof(BClassList)); + bestpath->next = NULL; + bestpath->type = TYPE(b); + } else if ((checkpath = CClass_GetBasePathRec(base->base, b, newOffset, depth + 1))) { + newpath = lalloc(sizeof(BClassList)); + newpath->next = checkpath; + newpath->type = TYPE(base->base); + if (!bestpath || CClass_IsMoreAccessiblePath(newpath, bestpath)) + bestpath = newpath; + } + } + + return bestpath; +} + +BClassList *CClass_GetBasePath(TypeClass *a, TypeClass *b, short *founddepth, Boolean *isambigbase) { + BClassList *path; + BClassList *result; + + if ((a->flags & (CLASS_FLAGS_2 | CLASS_FLAGS_800)) == CLASS_FLAGS_800) + CDecl_CompleteType(TYPE(a)); + if ((b->flags & (CLASS_FLAGS_2 | CLASS_FLAGS_800)) == CLASS_FLAGS_800) + CDecl_CompleteType(TYPE(b)); + + cclass_founddepth = 0; + cclass_isbase_mostderived = a; + cclass_isbase_foundoffset = -1; + cclass_isambigbase = 0; + + if ((path = CClass_GetBasePathRec(a, b, 0, 1))) { + *founddepth = cclass_founddepth; + *isambigbase = cclass_isambigbase; + + result = lalloc(sizeof(BClassList)); + result->next = path; + result->type = TYPE(a); + return result; + } else { + *isambigbase = 0; + return NULL; + } +} + +Boolean CClass_IsBaseClass(TypeClass *a, TypeClass *b, short *founddepth, Boolean pathcheckflag, Boolean ambigerrorflag) { + BClassList *path; + short depth; + Boolean isambigbase; + + if ((path = CClass_GetBasePath(a, b, &depth, &isambigbase))) { + if (isambigbase && ambigerrorflag) + CError_Error(CErrorStr188); + + if (pathcheckflag) + CClass_CheckPathAccess(path, NULL, ACCESSPUBLIC); + + if (founddepth) + *founddepth = depth; + + return 1; + } + + return 0; +} + +TypeClass *CClass_GetQualifiedClass(void) { + DeclInfo di; + + memclrw(&di, sizeof(di)); + CParser_GetDeclSpecs(&di, 0); + + if (IS_TYPE_CLASS(di.thetype)) + return TYPE_CLASS(di.thetype); + + return NULL; +} + +ENode *CClass_AccessPathCast(BClassList *path, ENode *expr, Boolean reverse) { + ClassList *base; + SInt32 offset; + + while (path && path->next) { + base = TYPE_CLASS(path->type)->bases; + while (1) { + if (base->base == TYPE_CLASS(path->next->type)) + break; + CError_ASSERT(1157, base = base->next); + } + + if (base->is_virtual) { + if (reverse) { + CError_Error(CErrorStr164); + break; + } + + if (!base->base->sominfo) { + offset = base->offset; + if (offset && !canadd(expr, offset)) { + expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), offset), EADD); + optimizecomm(expr); + } + + expr->rtype = CDecl_NewPointerType(CDecl_NewPointerType(TYPE(base->base))); + expr = makemonadicnode(expr, EINDIRECT); + expr->rtype = expr->data.monadic->rtype; + } + } else { + offset = base->offset; + if (offset) { + if (reverse) + offset = -offset; + if (!canadd(expr, offset)) { + expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), offset), EADD); + optimizecomm(expr); + } + } + } + + path = path->next; + } + + return expr; +} + +ENode *CClass_ClassPointerCast(ENode *expr, TypeClass *a, TypeClass *b, Boolean typconflag, Boolean ambigerrorflag, Boolean pathcheckflag) { + BClassList *path; + Boolean reverse; + short depth; + Boolean isambigbase; + + reverse = 0; + + if (a != b) { + if (!(path = CClass_GetBasePath(a, b, &depth, &isambigbase))) { + CError_ASSERT(1216, typconflag); + if ((path = CClass_GetBasePath(b, a, &depth, &isambigbase))) { + reverse = 1; + goto doCast; + } + } else { + doCast: + if (isambigbase && ambigerrorflag) + CError_Error(CErrorStr188); + if (pathcheckflag) + CClass_CheckPathAccess(path, NULL, ACCESSPUBLIC); + if (!(a->flags & CLASS_FLAGS_10) && !b->sominfo) + expr = CClass_AccessPathCast(path, expr, reverse); + } + } + + if (typconflag && ENODE_IS(expr, EINDIRECT) && IS_TYPE_POINTER_ONLY(expr->rtype)) + expr = makemonadicnode(expr, ETYPCON); + + return expr; +} + +ENode *CClass_DirectBasePointerCast(ENode *expr, TypeClass *a, TypeClass *b) { + ClassList *base; + VClassList *vbase; + BClassList *path; + BClassList list1; + BClassList list2; + short depth; + Boolean isambigbase; + + for (base = a->bases; base; base = base->next) { + if (base->base == b) { + list1.next = &list2; + list1.type = TYPE(a); + list2.next = NULL; + list2.type = TYPE(b); + return CClass_AccessPathCast(&list1, expr, 0); + } + } + + for (vbase = a->vbases; vbase; vbase = vbase->next) { + if (vbase->base == b) { + CError_ASSERT(1273, path = CClass_GetBasePath(a, b, &depth, &isambigbase)); + return CClass_AccessPathCast(path, expr, 0); + } + } + + CError_FATAL(1277); + return expr; +} + +SInt32 CClass_GetPathOffset(BClassList *path) { + SInt32 offset; + ClassList *base; + + offset = 0; + + while (path->next) { + if (path->type != path->next->type) { + for (base = TYPE_CLASS(path->type)->bases; base; base = base->next) { + if (base->base == TYPE_CLASS(path->next->type)) + break; + } + + if (!base) { + CError_Error(CErrorStr221); + return offset; + } + } + + if (base->is_virtual) + return -1; + offset += base->offset; + + path = path->next; + } + + return offset; +} + +Boolean CClass_ClassDominates(TypeClass *tclass, TypeClass *baseclass) { + ClassList *base; + + for (base = tclass->bases; base; base = base->next) { + if (base->base == baseclass || CClass_ClassDominates(base->base, baseclass)) + return 1; + } + + return 0; +} + +SInt32 CClass_VirtualBaseOffset(TypeClass *tclass, TypeClass *baseclass) { + VClassList *vbase; + + for (vbase = tclass->vbases; vbase; vbase = vbase->next) { + if (vbase->base == baseclass) + return vbase->offset; + } + + CError_FATAL(1342); + return 0; +} + +SInt32 CClass_VirtualBaseVTableOffset(TypeClass *tclass, TypeClass *baseclass) { + VClassList *vbase; + + for (vbase = tclass->vbases; vbase; vbase = vbase->next) { + if (vbase->base == baseclass) + return vbase->voffset; + } + + CError_FATAL(1359); + return 0; +} + +SInt32 CClass_GetMemberOffset(TypeClass *tclass, HashNameNode *name, ObjMemberVar **resultIvar) { + ObjMemberVar *ivar; + ClassList *base; + SInt32 offset; + SInt32 tmp; + Boolean foundflag; + + for (ivar = tclass->ivars; ivar; ivar = ivar->next) { + if (ivar->name == name) { + if (resultIvar) + *resultIvar = ivar; + return ivar->offset; + } + } + + for (base = tclass->bases, foundflag = 0; base; base = base->next) { + switch ((tmp = CClass_GetMemberOffset(base->base, name, resultIvar))) { + case -3: + case -2: + return tmp; + case -1: + break; + default: + if (base->is_virtual) + return -3; + if (foundflag) + return -2; + foundflag = 1; + offset = base->offset + tmp; + } + } + + return foundflag ? offset : -1; +} + +Boolean CClass_OverridesBaseMember(TypeClass *tclass, HashNameNode *name, Object *obj) { + NameSpaceObjectList *nsol; + ClassList *base; + Boolean result; + + result = 0; + for (base = tclass->bases; base; base = base->next) { + if (base->base->vtable) { + for (nsol = CScope_FindName(base->base->nspace, name); nsol; nsol = nsol->next) { + if ( + nsol->object->otype == OT_OBJECT && + OBJECT(nsol->object)->datatype == DVFUNC && + CClass_GetOverrideKind(TYPE_FUNC(OBJECT(nsol->object)->type), TYPE_FUNC(obj->type), 1) + ) + result = 1; + } + + if (CClass_OverridesBaseMember(base->base, name, obj)) + result = 1; + } + } + + return result; +} + +static OVClass *CClass_FindOVClass(OVClass *ovclass, TypeClass *tclass, SInt32 offset) { + OVClassBase *ovbase; + + if (ovclass->tclass == tclass && ovclass->offset == offset) + return ovclass; + + for (ovbase = ovclass->bases; ovbase; ovbase = ovbase->next) { + if ((ovclass = CClass_FindOVClass(ovbase->ovclass, tclass, offset))) + return ovclass; + } + + return NULL; +} + +static OVClass *CClass_BuildOVClassTree(OVClass *root, TypeClass *tclass, SInt32 offset, SInt32 voffset) { + ClassList *base; + Object *object; + OVClass *tree; + OVFunc *ovfunc; + OVClassBase *ovbase; + SInt32 vboffset; + SInt32 vbvoffset; + CScopeObjectIterator iter; + + tree = lalloc(sizeof(OVClass)); + memclrw(tree, sizeof(OVClass)); + + tree->tclass = tclass; + tree->offset = offset; + tree->voffset = voffset; + if (!root) + root = tree; + + CScope_InitObjectIterator(&iter, tclass->nspace); + while (1) { + if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter)))) + break; + + if (object->datatype == DVFUNC) { + ovfunc = lalloc(sizeof(OVFunc)); + memclrw(ovfunc, sizeof(OVFunc)); + + ovfunc->next = tree->vfuncs; + ovfunc->obj = object; + tree->vfuncs = ovfunc; + } + } + + for (base = tclass->bases; base; base = base->next) { + if (base->base->vtable || base->base->sominfo) { + ovbase = lalloc(sizeof(OVClassBase)); + memclrw(ovbase, sizeof(OVClassBase)); + + if (base->is_virtual) { + vboffset = CClass_VirtualBaseOffset(main_class, base->base); + if (!(ovbase->ovclass = CClass_FindOVClass(root, base->base, vboffset))) { + vbvoffset = CClass_VirtualBaseVTableOffset(main_class, base->base); + ovbase->ovclass = CClass_BuildOVClassTree(root, base->base, vboffset, vbvoffset); + } + ovbase->is_virtual = 1; + } else { + ovbase->ovclass = CClass_BuildOVClassTree( + root, + base->base, + offset + base->offset, + voffset + base->voffset); + ovbase->is_virtual = 0; + } + + ovbase->next = tree->bases; + tree->bases = ovbase; + } + } + + return tree; +} + +static Boolean CClass_IsBaseOf(OVClass *a, OVClass *b) { + OVClassBase *ovbase; + + for (ovbase = b->bases; ovbase; ovbase = ovbase->next) { + if ( + (ovbase->ovclass->tclass == a->tclass && ovbase->ovclass->offset == a->offset) || + CClass_IsBaseOf(a, ovbase->ovclass) + ) + { + if (!cclass_ovbase && ovbase->is_virtual) + cclass_ovbase = ovbase->ovclass; + return 1; + } + } + + return 0; +} + +static void CClass_FindOVFunc(OVClass *a, OVClass *b, OVFunc *func) { + OVFunc *scan; + OVClassBase *ovbase; + UInt8 overrideKind; + + if (CClass_IsBaseOf(b, a)) { + for (scan = a->vfuncs; scan; scan = scan->next) { + if ( + (func->obj->name == scan->obj->name) && + (overrideKind = CClass_GetOverrideKind(TYPE_FUNC(func->obj->type), TYPE_FUNC(scan->obj->type), 0)) + ) + { + if (func->ovc8) { + if (func->ovc8->tclass == a->tclass || CClass_ClassDominates(func->ovc8->tclass, a->tclass)) + return; + if (!CClass_ClassDominates(a->tclass, func->ovc8->tclass)) { + func->ovf10 = scan; + return; + } + } + + if (a == cclass_root) { + TYPE_FUNC(scan->obj->type)->flags |= FUNC_FLAGS_20; + if (overrideKind == 2) + TYPE_FUNC(scan->obj->type)->flags |= FUNC_FLAGS_400000; + } + + func->ovc8 = a; + func->ovfC = scan; + func->ovf10 = NULL; + return; + } + } + + for (ovbase = a->bases; ovbase; ovbase = ovbase->next) + CClass_FindOVFunc(ovbase->ovclass, b, func); + } +} + +static TypeList *CClass_GetCoVariantClassList(TypeList *list, TypeClass *tclass, Object *func, Boolean flag) { + Object *object; + TypeList *scan; + Type *type; + ClassList *base; + CScopeObjectIterator iter; + + if (!flag) { + CScope_InitObjectIterator(&iter, tclass->nspace); + while (1) { + if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter)))) + break; + + if ( + object->name == func->name && + object->datatype == DVFUNC && + CClass_GetOverrideKind(TYPE_FUNC(object->type), TYPE_FUNC(func->type), 0) == 2 + ) + { + CError_ASSERT(1686, + IS_TYPE_POINTER_ONLY(TYPE_FUNC(object->type)->functype) && + IS_TYPE_CLASS(TPTR_TARGET(TYPE_FUNC(object->type)->functype))); + + type = TPTR_TARGET(TYPE_FUNC(object->type)->functype); + for (scan = list; scan; scan = scan->next) { + if (scan->type == type) + break; + } + + if (!scan) { + scan = lalloc(sizeof(TypeList)); + scan->type = type; + scan->next = list; + list = scan; + } + } + } + } + + for (base = tclass->bases; base; base = base->next) { + if (base->base->vtable) + list = CClass_GetCoVariantClassList(list, base->base, func, 0); + } + + return list; +} + +static TypeMethod *CClass_GetCovariantType(TypeMethod *tmethod, Type *type) { + TypePointer *tptr; + TypeMethod *result; + + CError_ASSERT(1724, + IS_TYPE_METHOD(tmethod) && + IS_TYPE_POINTER_ONLY(tmethod->functype)); + + tptr = galloc(sizeof(TypePointer)); + *tptr = *TYPE_POINTER(tmethod->functype); + tptr->target = type; + + result = galloc(sizeof(TypeMethod)); + *result = *tmethod; + result->flags &= ~(FUNC_FLAGS_20 | FUNC_FLAGS_400000); + result->functype = TYPE(tptr); + return result; +} + +static Object *CClass_FindCovariantFunction(Object *func, Type *type) { + NameSpaceObjectList *nsol; + + nsol = CScope_FindName( + TYPE_METHOD(func->type)->theclass->nspace, + CMangler_GetCovariantFunctionName(func, type)); + + CError_ASSERT(1754, nsol && !nsol->next && nsol->object->otype == OT_OBJECT); + + return OBJECT(nsol->object); +} + +static ObjectList *CClass_DeclareCovariantFuncs(ObjectList *list, Object *func, TypeClass *tclass) { + Object *newfunc; + HashNameNode *name; + TypeList *types; + ObjectList *newlist; + + for (types = CClass_GetCoVariantClassList(NULL, tclass, func, 1); types; types = types->next) { + name = CMangler_GetCovariantFunctionName(func, types->type); + + newfunc = galloc(sizeof(Object)); + memclrw(newfunc, sizeof(Object)); + + newfunc->otype = OT_OBJECT; + newfunc->datatype = DFUNC; + newfunc->section = func->section; + newfunc->nspace = func->nspace; + newfunc->name = name; + newfunc->type = TYPE(CClass_GetCovariantType(TYPE_METHOD(func->type), types->type)); + newfunc->qual = func->qual & ~Q_INLINE; + newfunc->sclass = func->sclass; + newfunc->u.func.linkname = name; + + newlist = lalloc(sizeof(ObjectList)); + newlist->object = newfunc; + newlist->next = list; + list = newlist; + } + + return list; +} + +void CClass_DefineCovariantFuncs(Object *method, CI_FuncData *ifuncdata) { + NameSpace *nspace; + TypeList *types; + Object *covariantFunc; + Statement *stmt; + Type *tptr; + Statement firstStmt; + + for (types = CClass_GetCoVariantClassList(NULL, TYPE_METHOD(method->type)->theclass, method, 1); types; types = types->next) { + covariantFunc = CClass_FindCovariantFunction(method, types->type); + tptr = CDecl_NewPointerType(types->type); + + nspace = CFunc_FuncGenSetup(&firstStmt, covariantFunc); + CInline_UnpackIFunctionData(covariantFunc, ifuncdata, &firstStmt); + + for (stmt = &firstStmt; stmt; stmt = stmt->next) { + if (stmt->type == ST_RETURN && stmt->expr) + stmt->expr = CExpr_AssignmentPromotion(stmt->expr, tptr, ENODE_QUALS(stmt->expr), 0); + } + + CFunc_Gen(&firstStmt, covariantFunc, 0); + cscope_current = nspace->parent; + } +} + +static void CClass_OverrideOVClassTree(OVClass *ovclass) { + OVClassBase *ovbase; + OVFunc *ovfunc; + + if (cclass_root != ovclass) { + for (ovfunc = ovclass->vfuncs; ovfunc; ovfunc = ovfunc->next) + CClass_FindOVFunc(cclass_root, ovclass, ovfunc); + } + + for (ovbase = ovclass->bases; ovbase; ovbase = ovbase->next) + CClass_OverrideOVClassTree(ovbase->ovclass); +} + +static void CClass_AllocVTableRec(OVClass *ovclass) { + OVFunc *ovfunc; + Object *object; + SInt32 offset27; + SInt32 offset26; + SInt32 offset23; + OVClassBase *ovbase; + OLinkList *link; + + if (ovclass->alloced_vtable) + return; + + for (ovfunc = ovclass->vfuncs; ovfunc; ovfunc = ovfunc->next) { + offset27 = ovclass->voffset + TYPE_METHOD(ovfunc->obj->type)->x1E + CABI_GetVTableOffset(ovclass->tclass); + CError_ASSERT(1867, offset27 < vtable_data_size); + + if (!(vtable_object_data[offset27])) { + if (ovfunc->ovfC) { + object = ovfunc->ovfC->obj; + if ( + (TYPE_FUNC(object->type)->flags & FUNC_FLAGS_400000) && + CClass_GetOverrideKind(TYPE_FUNC(ovfunc->obj->type), TYPE_FUNC(object->type), 0) == 2 + ) + { + CError_ASSERT(1887, + IS_TYPE_POINTER_ONLY(TYPE_FUNC(ovfunc->obj->type)->functype) && + IS_TYPE_CLASS(TPTR_TARGET(TYPE_FUNC(ovfunc->obj->type)->functype))); + object = CClass_FindCovariantFunction( + object, + TPTR_TARGET(TYPE_FUNC(ovfunc->obj->type)->functype)); + } + + if ((offset26 = ovfunc->ovc8->offset - ovclass->offset)) { + if (!(TYPE_FUNC(object->type)->flags & FUNC_FLAGS_8)) { + cclass_ovbase = NULL; + CError_ASSERT(1899, CClass_IsBaseOf(ovclass, ovfunc->ovc8)); + + if (cclass_ovbase && (main_class->flags & CLASS_FLAGS_8000)) { + offset23 = ovclass->offset - cclass_ovbase->offset; + offset23 = CABI_GetCtorOffsetOffset(cclass_ovbase->tclass, NULL) - offset23; + CError_ASSERT(1906, offset23 > 0); + object = CClass_ThunkObject(object, offset26, 0, offset23); + } else { + object = CClass_ThunkObject(object, offset26, 0, -1); + } + } + } + } else { + object = ovfunc->obj; + } + + if (!(TYPE_FUNC(object->type)->flags & FUNC_FLAGS_8)) { + link = lalloc(sizeof(OLinkList)); + link->next = vtable_object_links; + link->obj = object; + link->offset = offset27; + link->somevalue = 0; + vtable_object_links = link; + vtable_object_data[offset27] = 1; + } + } + } + + ovclass->alloced_vtable = 1; + + for (ovbase = ovclass->bases; ovbase; ovbase = ovbase->next) + CClass_AllocVTableRec(ovbase->ovclass); +} + +static Object *CClass_CheckClass(OVClass *ovclass, Boolean errorflag) { + Object *object; + Object *check; + OVFunc *ovfunc; + OVClassBase *ovbase; + + object = NULL; + + for (ovfunc = ovclass->vfuncs; ovfunc; ovfunc = ovfunc->next) { + if (ovfunc->ovf10 && errorflag) + CError_Error(CErrorStr251, main_class, 0, ovfunc->obj, ovfunc->ovfC->obj, ovfunc->ovf10->obj); + + if (!object) { + check = ovfunc->ovfC ? ovfunc->ovfC->obj : ovfunc->obj; + if (TYPE_FUNC(check->type)->flags & FUNC_FLAGS_8) + object = check; + } + } + + for (ovbase = ovclass->bases; ovbase; ovbase = ovbase->next) { + if (object) + CClass_CheckClass(ovbase->ovclass, errorflag); + else + object = CClass_CheckClass(ovbase->ovclass, errorflag); + } + + return object; +} + +static void CClass_AllocVTable(TypeClass *tclass) { + OVClass *ovclass; + + main_class = tclass; + ovclass = CClass_BuildOVClassTree(NULL, tclass, 0, 0); + cclass_root = ovclass; + CClass_OverrideOVClassTree(ovclass); + CClass_CheckClass(ovclass, 1); + CClass_AllocVTableRec(ovclass); +} + +static Object *CClass_CheckVirtuals(TypeClass *tclass) { + OVClass *ovclass; + + main_class = tclass; + ovclass = CClass_BuildOVClassTree(NULL, tclass, 0, 0); + cclass_root = ovclass; + CClass_OverrideOVClassTree(ovclass); + return CClass_CheckClass(ovclass, 0); +} + +static void CClass_CheckVirtualBaseOverrides(OVClass *a, OVClass *b, Boolean flag) { + VClassList *vbase; + OVFunc *ovfunc; + OVClassBase *ovbase; + + if (flag) { + for (ovfunc = b->vfuncs; ovfunc; ovfunc = ovfunc->next) { + if (ovfunc->ovfC) { + cclass_ovbase = NULL; + CError_ASSERT(2040, CClass_IsBaseOf(b, ovfunc->ovc8)); + + if (cclass_ovbase) { + for (vbase = a->tclass->vbases; vbase; vbase = vbase->next) { + if (vbase->base == cclass_ovbase->tclass) + break; + } + + CError_ASSERT(2047, vbase); + vbase->has_override = 1; + } + } + } + } + + for (ovbase = b->bases; ovbase; ovbase = ovbase->next) { + CClass_CheckVirtualBaseOverrides(a, ovbase->ovclass, flag || ovbase->is_virtual); + } +} + +static void CClass_CheckHideVirtual(OVClass *a, OVClass *b) { + OVClassBase *ovbase; + OVFunc *ovfunc; + Object *foundObject; + Boolean isAlias; + Object *object; + CScopeObjectIterator iter; + + if (a != b) { + for (ovfunc = b->vfuncs; ovfunc; ovfunc = ovfunc->next) { + if (ovfunc->ovc8 != a) { + foundObject = NULL; + isAlias = 0; + CScope_InitObjectIterator(&iter, a->tclass->nspace); + + while (1) { + if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter)))) + break; + + if (object->name == ovfunc->obj->name && IS_TYPE_FUNC(object->type)) { + if (object->datatype != DALIAS) { + if (!(TYPE_FUNC(object->type)->flags & FUNC_FLAGS_20)) + foundObject = object; + } else { + if (object->u.alias.object == ovfunc->obj) { + // don't show a warning if this is just an alias to the base function + isAlias = 1; + break; + } + } + } + } + + if (foundObject && !isAlias) + CError_Warning(CErrorStr225, foundObject, ovfunc->obj); + } + } + } + + for (ovbase = b->bases; ovbase; ovbase = ovbase->next) + CClass_CheckHideVirtual(a, ovbase->ovclass); +} + +void CClass_CheckOverrides(TypeClass *tclass) { + OVClass *tree; + Object *object; + ObjectList *objlist; + ClassList *base; + VClassList *vbase; + int i; + CScopeObjectIterator iter; + + i = 0; + for (base = tclass->bases; base; base = base->next) { + base->offset = i; + base->voffset = i; + i++; + } + for (vbase = tclass->vbases; vbase; vbase = vbase->next) { + vbase->offset = i; + vbase->voffset = i; + i++; + } + + main_class = tclass; + tree = CClass_BuildOVClassTree(NULL, tclass, 0, 0); + cclass_root = tree; + + CClass_OverrideOVClassTree(tree); + if (CClass_CheckClass(tree, 0)) + tclass->flags |= CLASS_FLAGS_ABSTRACT; + + if (copts.warn_hidevirtual) + CClass_CheckHideVirtual(tree, tree); + + if (tclass->flags & CLASS_FLAGS_8000) + CClass_CheckVirtualBaseOverrides(tree, tree, 0); + + objlist = NULL; + CScope_InitObjectIterator(&iter, tclass->nspace); + while (1) { + if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter)))) + break; + + if (object->datatype == DVFUNC) { + CError_ASSERT(2175, IS_TYPE_FUNC(object->type)); + if (TYPE_FUNC(object->type)->flags & FUNC_FLAGS_400000) + objlist = CClass_DeclareCovariantFuncs(objlist, object, tclass); + } + } + + while (objlist) { + CScope_AddObject(tclass->nspace, objlist->object->name, OBJ_BASE(objlist->object)); + objlist = objlist->next; + } + + for (base = tclass->bases; base; base = base->next) { + base->offset = 0; + base->voffset = 0; + } + for (vbase = tclass->vbases; vbase; vbase = vbase->next) { + vbase->offset = 0; + vbase->voffset = 0; + } +} + +static void CClass_FindDominator(TypeClass *tclass1, SInt32 offset1, Object *object1, TypeClass *tclass2, SInt32 offset2, TypeClass *tclass3) { + Object *object; + ClassList *base; + CScopeObjectIterator iter; + + CScope_InitObjectIterator(&iter, tclass1->nspace); + while (1) { + if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter)))) + break; + + if ( + object->name == cclass_dominator_vobject->name && + object->datatype == DVFUNC && + CClass_GetOverrideKind(TYPE_FUNC(cclass_dominator_vobject->type), TYPE_FUNC(object->type), 0) + ) + { + if (object == cclass_dominator_vobject && offset1 == cclass_dominator_voffset) { + if (object1) { + if (cclass_dominator_oobject && cclass_dominator_ooffset != offset2) { + if (CClass_ClassDominates(cclass_dominator_oclass, tclass2)) + return; + if (!CClass_ClassDominates(tclass2, cclass_dominator_oclass)) { + cclass_dominator_eobject = object1; + cclass_vbase = tclass3; + return; + } + } + + cclass_dominator_oobject = object1; + cclass_dominator_ooffset = offset2; + cclass_dominator_oclass = tclass2; + cclass_dominator_eobject = NULL; + cclass_vbase = tclass3; + } + return; + } else { + if (!object1) { + object1 = object; + tclass2 = tclass1; + offset2 = offset1; + } + break; + } + } + } + + for (base = tclass1->bases; base; base = base->next) { + if (base->base->vtable) { + if (!base->is_virtual) { + CClass_FindDominator(base->base, offset1 + base->offset, object1, tclass2, offset2, tclass3); + } else { + SInt32 vboffset = CClass_VirtualBaseOffset(main_class, base->base); + CClass_FindDominator(base->base, vboffset, object1, tclass2, offset2, base->base); + } + } + } +} + +static void CClass_ConstructVTable(TypeClass *tclass, SInt32 voffset, SInt32 offset, TypeClass *baseclass) { + Object *object; + Object *thunkobject; + SInt32 newoffset; + SInt32 newvoffset; + ClassList *base; + SInt32 thunkoffset; + OLinkList *olink; + CScopeObjectIterator iter; + + CScope_InitObjectIterator(&iter, tclass->nspace); + while (1) { + if (!(object = OBJECT(CScope_NextObjectIteratorObject(&iter)))) + break; + + if (object->datatype == DVFUNC) { + newoffset = voffset + TYPE_METHOD(object->type)->x1E + CABI_GetVTableOffset(tclass); + CError_ASSERT(2288, newoffset < vtable_data_size); + + if (!vtable_object_data[newoffset]) { + cclass_dominator_vobject = object; + cclass_dominator_voffset = offset; + cclass_dominator_oobject = NULL; + cclass_dominator_ooffset = offset; + CClass_FindDominator(main_class, 0, NULL, NULL, 0, NULL); + + if (cclass_dominator_oobject) { + if (cclass_dominator_eobject) + CError_Error(CErrorStr251, main_class, 0, cclass_dominator_vobject, cclass_dominator_oobject, cclass_dominator_eobject); + } else { + cclass_dominator_oobject = object; + cclass_vbase = NULL; + } + + vtable_object_data[newoffset] = 1; + + if (!(TYPE_FUNC(cclass_dominator_oobject->type)->flags & FUNC_FLAGS_8)) { + if (!check_pures) { + thunkobject = cclass_dominator_oobject; + if ((thunkoffset = cclass_dominator_ooffset - offset)) { + if (cclass_vbase && (main_class->flags & CLASS_FLAGS_8000)) { + thunkobject = CClass_ThunkObject(cclass_dominator_oobject, thunkoffset, 0, + CABI_GetCtorOffsetOffset(cclass_vbase, tclass)); + } else { + thunkobject = CClass_ThunkObject(cclass_dominator_oobject, thunkoffset, 0, -1); + } + } + + olink = lalloc(sizeof(OLinkList)); + olink->next = vtable_object_links; + olink->obj = thunkobject; + olink->offset = newoffset; + olink->somevalue = 0; + vtable_object_links = olink; + } + } else { + found_pure = cclass_dominator_oobject; + } + } + } + } + + for (base = tclass->bases; base; base = base->next) { + if (base->base->vtable) { + if (base->is_virtual) { + newoffset = CClass_VirtualBaseOffset(main_class, base->base); + newvoffset = CClass_VirtualBaseVTableOffset(main_class, base->base); + CClass_ConstructVTable( + base->base, + newvoffset, + newoffset, + base->base + ); + } else { + CClass_ConstructVTable( + base->base, + voffset + base->voffset, + offset + base->offset, + baseclass + ); + } + } + } +} + +void CClass_ClassDefaultFuncAction(TypeClass *tclass) { +} + +void CClass_ClassAction(TypeClass *tclass) { + if (tclass->sominfo) { + CSOM_GenerateClassStructures(tclass); + } else if (tclass->vtable) { + vtable_data_size = tclass->vtable->size; + vtable_object_data = lalloc(vtable_data_size); + memclrw(vtable_object_data, vtable_data_size); + + main_class = tclass; + vtable_object_links = NULL; + found_pure = NULL; + check_pures = 0; + + CClass_AllocVTable(tclass); + + memclrw(vtable_object_data, vtable_data_size); + if (copts.useRTTI && !(tclass->flags & (CLASS_FLAGS_10 | CLASS_FLAGS_2000))) + vtable_object_links = CRTTI_ConstructVTableHeaders(tclass, vtable_object_data, vtable_object_links); + + CError_ASSERT(2492, tclass->vtable->object->type->size == tclass->vtable->size); + CInit_DeclareData(tclass->vtable->object, vtable_object_data, vtable_object_links, tclass->vtable->size); + } +} + +void CClass_MakeStaticActionClass(TypeClass *tclass) { + if (tclass->vtable) { + tclass->vtable->object->sclass = TK_STATIC; + tclass->vtable->object->qual |= Q_20000; + if (!(tclass->vtable->object->flags & OBJECT_FLAGS_2)) { + CParser_NewCallBackAction(tclass->vtable->object, tclass); + } else if (cparamblkptr->isPrecompiling != 1) { + CParser_NewClassAction(tclass); + } + } +} + +Object *CClass_CheckPures(TypeClass *tclass) { + return CClass_CheckVirtuals(tclass); +} + +void CClass_MemberDef(Object *obj, TypeClass *tclass) { + switch (tclass->action) { + case CLASS_ACTION_0: + break; + case CLASS_ACTION_1: + if (IS_TYPE_FUNC(obj->type) && (TYPE_FUNC(obj->type)->flags & FUNC_FLAGS_4)) { + if (obj->qual & Q_INLINE) { + if (tclass->sominfo) + CError_Error(CErrorStr280); + tclass->action = CLASS_ACTION_0; + CClass_MakeStaticActionClass(tclass); + } else if (cparamblkptr->isPrecompiling != 1) { + CParser_NewClassAction(tclass); + } + } + break; + case CLASS_ACTION_2: + CError_FATAL(2682); + break; + case CLASS_ACTION_3: + break; + default: + CError_FATAL(2701); + } +} + +Object *CClass_ThisSelfObject(void) { + ObjectList *list; + + if (cscope_currentfunc && cscope_currentclass) { + if (cscope_currentclass->objcinfo) { + for (list = arguments; list; list = list->next) { + if (list->object->name == self_name_node) + return list->object; + } + CError_Error(CErrorStr301); + } else { + if (cscope_is_member_func) { + for (list = arguments; list; list = list->next) { + if (list->object->name == this_name_node) + return list->object; + } + } + CError_Error(CErrorStr189); + } + } + + CError_Error(copts.cplusplus ? CErrorStr189 : CErrorStr301); + return NULL; +} + +ENode *CClass_CreateThisSelfExpr(void) { + Object *object; + ENode *expr; + + if (!(object = CClass_ThisSelfObject())) + return NULL; + + expr = create_objectrefnode(object); + expr->rtype = CDecl_NewPointerType(TYPE(cscope_currentclass)); + expr = makemonadicnode(expr, EINDIRECT); + expr->data.monadic->rtype = CDecl_NewPointerType(expr->rtype); + + return expr; +} + +static AccessType CClass_BaseMemberAccess(BClassList *path, AccessType access) { + ClassList *base; + + if (path->next) { + access = CClass_BaseMemberAccess(path->next, access); + switch (access) { + case ACCESSPRIVATE: + case ACCESSNONE: + return ACCESSNONE; + } + + for (base = TYPE_CLASS(path->type)->bases; ; base = base->next) { + if (!base) + return ACCESSNONE; + + if (base->base == TYPE_CLASS(path->next->type)) { + switch (base->access) { + case ACCESSNONE: + access = ACCESSNONE; + break; + case ACCESSPROTECTED: + if (access == ACCESSPUBLIC) + access = ACCESSPROTECTED; + break; + case ACCESSPRIVATE: + if (access == ACCESSPRIVATE) + access = ACCESSNONE; + else + access = ACCESSPRIVATE; + break; + case ACCESSPUBLIC: + break; + } + break; + } + } + } + + return access; +} + +static Boolean CClass_CanAccess(BClassList *path, AccessType access) { + AccessType access2; + BClassList *scan; + BClassList *next; + TypeClass *prevclass; + TypeClass *tclass; + ClassList *base; + ClassFriend *cfriend; + + tclass = TYPE_CLASS(path->type); + access2 = access; + if ((scan = path->next)) { + if (access2 != ACCESSPRIVATE) { + prevclass = tclass; + while (scan) { + for (base = prevclass->bases; base; base = base->next) { + if (base->base == TYPE_CLASS(scan->type)) + break; + } + + if (!base) + return 0; + + switch (base->access) { + case ACCESSNONE: + access2 = ACCESSNONE; + break; + case ACCESSPROTECTED: + if (access2 == ACCESSPUBLIC) + access2 = ACCESSPROTECTED; + break; + case ACCESSPRIVATE: + if (access2 == ACCESSPRIVATE) + access2 = ACCESSNONE; + else + access2 = ACCESSPRIVATE; + break; + case ACCESSPUBLIC: + break; + } + + prevclass = TYPE_CLASS(scan->type); + scan = scan->next; + } + } else { + access2 = ACCESSNONE; + } + } + + if (access2 == ACCESSPUBLIC) + return 1; + + if (access2 != ACCESSNONE) { + if (cscope_currentclass == tclass) + return 1; + if (cobjc_currentclass == tclass) + return 1; + + for (cfriend = tclass->friends; cfriend; cfriend = cfriend->next) { + if (cfriend->isclass) { + if (cfriend->u.theclass == cscope_currentclass) + return 1; + } else { + if (cfriend->u.obj == cscope_currentfunc) + return 1; + } + } + } + + for (scan = path; scan->next; scan = scan->next) { + if (CClass_CanAccess(scan->next, access)) { + if ((next = scan->next->next) || access != ACCESSPUBLIC) { + scan->next->next = NULL; + if (CClass_CanAccess(path, ACCESSPUBLIC)) { + scan->next->next = next; + return 1; + } + scan->next->next = next; + } + } + } + + return 0; +} + +void CClass_CheckPathAccess(BClassList *path, Object *obj, AccessType access) { + if (!CClass_CanAccess(path, access)) { + if (path && obj) + CError_Error(CErrorStr381, path->type, 0, obj); + else + CError_Error(CErrorStr187); + } +} + +static BClassList *CClass_PathCleanup(BClassList *path, TypeClass *tclass) { + BClassList *first; + ClassList *base; + + first = path; + + while (1) { + if (!path->next) { + if (!tclass) + return first; + if (path->type == TYPE(tclass)) + return first; + return NULL; + } + + if (path->type != path->next->type) { + for (base = TYPE_CLASS(path->type)->bases; base; base = base->next) { + if (base->base == TYPE_CLASS(path->next->type)) + break; + } + + if (base) { + path = path->next; + } else { + first = path = path->next; + } + } else { + path->next = path->next->next; + } + } +} + +void CClass_CheckStaticAccess(BClassList *path, TypeClass *tclass, AccessType access) { + ClassFriend *cfriend; + + if (path) { + path = CClass_PathCleanup(path, tclass); + if (path && path->next) { + if (!CClass_CanAccess(path, access)) + CError_Error(CErrorStr187); + return; + } + } + + switch (access) { + case ACCESSPUBLIC: + return; + case ACCESSPRIVATE: + case ACCESSPROTECTED: + if (tclass == cscope_currentclass) + return; + + for (cfriend = tclass->friends; cfriend; cfriend = cfriend->next) { + if (cfriend->isclass) { + if (cfriend->u.theclass == cscope_currentclass) + return; + } else { + if (cfriend->u.obj == cscope_currentfunc) + return; + } + } + case ACCESSNONE: + CError_Warning(CErrorStr187); + return; + default: + CError_FATAL(3013); + } +} + +void CClass_CheckObjectAccess(BClassList *path, Object *obj) { + short depth; + Boolean isambigbase; + + if (obj->nspace && obj->nspace->theclass) { + if (!path && cscope_currentclass) + path = CClass_GetBasePath(cscope_currentclass, obj->nspace->theclass, &depth, &isambigbase); + + CClass_CheckStaticAccess(path, obj->nspace->theclass, obj->access); + } +} + +void CClass_CheckEnumAccess(BClassList *path, ObjEnumConst *objec) { + if (path) { + if ((path = CClass_PathCleanup(path, NULL))) { + if (!CClass_CanAccess(path, objec->access)) + CError_Error(CErrorStr187); + return; + } + } + + if ( + objec->access != ACCESSPUBLIC && + IS_TYPE_ENUM(objec->type) && + TYPE_ENUM(objec->type)->nspace && + TYPE_ENUM(objec->type)->nspace->theclass + ) + CClass_CheckStaticAccess(NULL, TYPE_ENUM(objec->type)->nspace->theclass, objec->access); +} + +static Type *CClass_PointerTypeCopy(Type *type) { + Type *copy; + + switch (type->type) { + case TYPEPOINTER: + case TYPEARRAY: + copy = galloc(sizeof(TypePointer)); + *TYPE_POINTER(copy) = *TYPE_POINTER(type); + TPTR_TARGET(copy) = CClass_PointerTypeCopy(TPTR_TARGET(copy)); + return copy; + case TYPEMEMBERPOINTER: + copy = galloc(sizeof(TypeMemberPointer)); + *TYPE_MEMBER_POINTER(copy) = *TYPE_MEMBER_POINTER(type); + return copy; + default: + return type; + } +} + +Type *CClass_CombineClassAccessQualifiers(Type *type, UInt32 qual1, UInt32 qual2, UInt32 *outflags) { + Type *inner; + + qual2 = qual2 & (Q_CONST | Q_VOLATILE); + if (qual1 & Q_MUTABLE) + qual2 &= ~Q_CONST; + qual1 = qual1 & (Q_CONST | Q_VOLATILE); + + inner = type; + while (IS_TYPE_ARRAY(inner)) + inner = TPTR_TARGET(inner); + + switch (inner->type) { + case TYPEMEMBERPOINTER: + case TYPEPOINTER: + if (qual2) { + type = CClass_PointerTypeCopy(type); + inner = type; + while (IS_TYPE_ARRAY(inner)) + inner = TPTR_TARGET(inner); + + switch (inner->type) { + case TYPEPOINTER: + TPTR_QUAL(inner) |= qual2; + break; + case TYPEMEMBERPOINTER: + TYPE_MEMBER_POINTER(inner)->qual |= qual2; + break; + default: + CError_FATAL(3125); + } + } + break; + default: + qual1 |= qual2; + } + + *outflags = qual1; + return type; +} + +static void CClass_OptimizeBitFieldAccess(Type **ptype, SInt32 *poffset) { + Type *innertype; + TypeBitfield *newtype; + short i; + + innertype = TYPE_BITFIELD(*ptype)->bitfieldtype; + if (TYPE_BITFIELD(*ptype)->unkB == 8) { + switch (TYPE_BITFIELD(*ptype)->unkA) { + case 0: + i = 0; + break; + case 8: + i = 1; + break; + case 16: + i = 2; + break; + case 24: + i = 3; + break; + default: + i = -1; + break; + } + + if (i >= 0) { + if (innertype->size != 1) { + if (is_unsigned(TYPE_BITFIELD(*ptype)->bitfieldtype)) + *ptype = TYPE(&stunsignedchar); + else + *ptype = TYPE(&stsignedchar); + } else { + *ptype = innertype; + } + *poffset += i; + return; + } + } + + if (TYPE_BITFIELD(*ptype)->unkB == 16) { + switch (TYPE_BITFIELD(*ptype)->unkA) { + case 0: + i = 0; + break; + case 16: + i = 2; + break; + default: + i = -1; + break; + } + + if (i >= 0) { + if (innertype->size != stsignedshort.size) { + if (is_unsigned(innertype)) + *ptype = TYPE(&stunsignedshort); + else + *ptype = TYPE(&stsignedshort); + } else { + *ptype = innertype; + } + *poffset += i; + return; + } + } + + if (TYPE_BITFIELD(*ptype)->unkB == 32 && TYPE_BITFIELD(*ptype)->unkA == 0) { + if (innertype->size != stsignedlong.size) { + if (is_unsigned(innertype)) + *ptype = TYPE(&stunsignedlong); + else + *ptype = TYPE(&stsignedlong); + } else { + *ptype = innertype; + } + return; + } + + if ((*ptype)->size != stsignedchar.size) { + i = TYPE_BITFIELD(*ptype)->unkA + TYPE_BITFIELD(*ptype)->unkB - 1; + + if (TYPE_BITFIELD(*ptype)->unkB < 8 && (TYPE_BITFIELD(*ptype)->unkA & 0xFFF8) == (i & 0xFFF8)) { + newtype = galloc(sizeof(TypeBitfield)); + *newtype = *TYPE_BITFIELD(*ptype); + *ptype = TYPE(newtype); + + i = 0; + if (newtype->unkA >= 8) + i = 1; + if (newtype->unkA >= 16) + i = 2; + if (newtype->unkA >= 24) + i = 3; + *poffset += i; + newtype->unkA -= 8 * i; + + newtype->bitfieldtype = is_unsigned(innertype) ? TYPE(&stunsignedchar) : TYPE(&stsignedchar); + newtype->size = newtype->bitfieldtype->size; + return; + } + + if ((*ptype)->size != stsignedshort.size) { + if (TYPE_BITFIELD(*ptype)->unkB < 16 && (TYPE_BITFIELD(*ptype)->unkA & 0xFFF0) == (i & 0xFFF0)) { + newtype = galloc(sizeof(TypeBitfield)); + *newtype = *TYPE_BITFIELD(*ptype); + *ptype = TYPE(newtype); + + i = 0; + if (newtype->unkA >= 16) + i = stsignedshort.size; + *poffset += i; + newtype->unkA -= 8 * i; + + newtype->bitfieldtype = is_unsigned(innertype) ? TYPE(&stunsignedshort) : TYPE(&stsignedshort); + newtype->size = newtype->bitfieldtype->size; + return; + } + } + } +} + +ENode *CClass_AccessMember(ENode *classexpr, Type *type, UInt32 qual, SInt32 offset) { + Type *innertype; + UInt32 flags; + + innertype = NULL; + + if (IS_TYPE_CLASS(classexpr->rtype) && (TYPE_CLASS(classexpr->rtype)->flags & CLASS_FLAGS_1)) { + classexpr = makemonadicnode(classexpr, EINDIRECT); + classexpr->data.monadic->rtype = CDecl_NewPointerType(classexpr->rtype); + } + + if (IS_TYPE_BITFIELD(type)) { + innertype = TYPE_BITFIELD(type)->bitfieldtype; + CClass_OptimizeBitFieldAccess(&type, &offset); + } + + if (offset && !canadd(classexpr->data.monadic, offset)) { + classexpr->data.monadic = makediadicnode( + classexpr->data.monadic, + intconstnode(TYPE(&stunsignedlong), offset), + EADD); + optimizecomm(classexpr->data.monadic); + } + + if (innertype) { + if (IS_TYPE_BITFIELD(type)) { + classexpr->data.monadic = makemonadicnode(classexpr->data.monadic, EBITFIELD); + classexpr->data.monadic->rtype = type; + classexpr->rtype = TYPE_BITFIELD(type)->bitfieldtype; + } else { + classexpr->rtype = type; + } + } else { + classexpr->rtype = type; + } + + classexpr->rtype = CClass_CombineClassAccessQualifiers(classexpr->rtype, qual, ENODE_QUALS(classexpr), &flags); + classexpr->flags = flags; + return classexpr; +} diff --git a/compiler_and_linker/unsorted/CDecl.c b/compiler_and_linker/unsorted/CDecl.c index 63f2d0f..0ee3cf8 100644 --- a/compiler_and_linker/unsorted/CDecl.c +++ b/compiler_and_linker/unsorted/CDecl.c @@ -1,68 +1,30 @@ #include "compiler/CDecl.h" -#include "compiler/CompilerTools.h" -#include "compiler/CError.h" -#include "compiler/objects.h" -#include "compiler/scopes.h" -#include "compiler/templates.h" -#include "compiler/tokens.h" -#include "compiler/CPrep.h" -#include "compiler/CPrepTokenizer.h" -#include "compiler/CMangler.h" +#include "compiler/CABI.h" +#include "compiler/CBrowse.h" #include "compiler/CClass.h" -#include "compiler/CParser.h" +#include "compiler/CError.h" +#include "compiler/CException.h" +#include "compiler/CExpr.h" #include "compiler/CFunc.h" #include "compiler/CInit.h" +#include "compiler/CInline.h" #include "compiler/CInt64.h" -#include "compiler/CExpr.h" #include "compiler/CMachine.h" -#include "compiler/CInline.h" -#include "compiler/CABI.h" - -// TODO MOVE ME -extern void CExcept_ScanExceptionSpecification(TypeFunc *tfunc); -extern void CExcept_CompareSpecifications(ExceptSpecList *a, ExceptSpecList *b); -extern void CObjC_ParseDefs(TypeStruct *tstruct); -extern void CTempl_Parse(TypeClass *tclass, short access); -extern Boolean CTempl_InstantiateTemplateClass(TemplClass *cls); -extern Boolean CTemplTool_IsTemplateArgumentDependentType(Type *type); -extern TemplClass *CTemplTool_GetSelfRefTemplate(Type *type); -extern Type *CTemplTool_ResolveMemberSelfRefs(TypeClass *tclass, Type *type, UInt32 *qual); -extern Boolean CTempl_IsQualifiedMember(DeclInfo *declinfo, Type *type, NameSpace **nspace); -extern Object *CTempl_TemplateFunctionCheck(DeclInfo *declinfo, NameSpaceObjectList *list); -extern TemplArg *CTempl_ParseUncheckTemplArgs(void *a, Boolean flag); -extern TemplArg *CTemplTool_MakeGlobalTemplArgCopy(TemplArg *args); -extern void CTemplClass_RegisterFriend(TemplClass *tmclass, DeclInfo *declinfo); -extern void CTemplClass_RegisterBaseClass(TemplClass *tmclass, Type *baseclass, short access, Boolean is_virtual); -extern void CTemplClass_RegisterObjectDef(TemplClass *tmclass, ObjBase *obj); -extern void CTemplClass_RegisterObjectInit(TemplClass *tmclass, ObjBase *obj, ENode *expr); -extern void CTemplClass_DefineMember(TemplClass *tmclass, Object *obj, FileOffsetInfo *fileoffset, TStream *stream); -extern void CTemplClass_CompleteClass(TemplClass *templ, DeclE *decle); -extern void CTemplClass_RegisterEnumType(TemplClass *tmclass, TypeEnum *tenum); -extern void CTemplClass_RegisterEnumerator(TemplClass *tmclass, ObjEnumConst *oec, ENode *expr); -extern TypeClass *CTemplClass_DefineNestedClass(TemplClass *tmclass, HashNameNode *name, short mode); -extern void CSOM_FixNewDeleteFunctype(TypeFunc *tfunc); -extern void CSOM_CheckFuncType(TypeFunc *tfunc); -extern void CSOM_ClassComplete(TypeClass *tclass); -extern void CSOM_MakeSOMClass(TypeClass *tclass); -typedef struct BrowseStruct { - void *x0; - void *x4; - void *x8; - void *xC; -} BrowseStruct; -extern void CBrowse_BeginStruct(DeclInfo *declinfo, TypeStruct *type, BrowseStruct *bs); -extern void CBrowse_EndStruct(SInt32 offset, BrowseStruct *bs); -extern void CBrowse_AddStructMember(StructMember *member, SInt32 tokenoffset, SInt32 fileoffset); -extern void CBrowse_BeginClass(DeclInfo *declinfo, BrowseStruct *bs); -extern void CBrowse_EndClass(SInt32 offset, BrowseStruct *bs); -extern void CBrowse_NewTypedef(NameSpace *nspace, HashNameNode *name, CPrepFileInfo *file, SInt32 tokenline, SInt32 tokenoffset, SInt32 fileoffset); -extern void CBrowse_NewData(Object *obj, CPrepFileInfo *file, SInt32 tokenline, SInt32 tokenoffset, SInt32 fileoffset); -extern void CBrowse_NewFunction(Object *obj, CPrepFileInfo *file, CPrepFileInfo *file2, SInt32 tokenoffset, SInt32 fileoffset); -extern void CBrowse_NewEnum(NameSpace *nspace, HashNameNode *name, CPrepFileInfo *file, CPrepFileInfo *file2, SInt32 tokenoffset, SInt32 fileoffset); -extern void CBrowse_NewEnumConstant(NameSpace *nspace, HashNameNode *name, CPrepFileInfo *file, CPrepFileInfo *file2, SInt32 tokenoffset, SInt32 fileoffset); -extern void CBrowse_AddClassMemberData(Object *obj, SInt32 tokenoffset, SInt32 fileoffset); -extern void CBrowse_AddClassMemberFunction(Object *obj, SInt32 tokenoffset, SInt32 fileoffset); -extern void CBrowse_AddClassMemberVar(ObjMemberVar *obj, SInt32 tokenoffset, SInt32 fileoffset); +#include "compiler/CMangler.h" +#include "compiler/CObjC.h" +#include "compiler/CParser.h" +#include "compiler/CPrep.h" +#include "compiler/CPrepTokenizer.h" +#include "compiler/CSOM.h" +#include "compiler/CTemplateClass.h" +#include "compiler/CTemplateFunc.h" +#include "compiler/CTemplateNew.h" +#include "compiler/CTemplateTools.h" +#include "compiler/CompilerTools.h" +#include "compiler/objects.h" +#include "compiler/scopes.h" +#include "compiler/templates.h" +#include "compiler/tokens.h" AccessType global_access; FileOffsetInfo member_fileoffset; @@ -213,7 +175,7 @@ void CDecl_CompleteType(Type *type) { } if ((TYPE_CLASS(type)->flags & (CLASS_FLAGS_2 | CLASS_FLAGS_800)) == CLASS_FLAGS_800) - CTempl_InstantiateTemplateClass(TEMPL_CLASS(type)); + CTempl_InstantiateTemplateClass(TYPE_CLASS(type)); } Boolean IsCompleteType(Type *type) { @@ -231,8 +193,14 @@ Boolean IsCompleteType(Type *type) { } return 1; case TYPECLASS: - if (!(TYPE_CLASS(type)->flags & CLASS_FLAGS_2) && (!(TYPE_CLASS(type)->flags & CLASS_FLAGS_800) || !CTempl_InstantiateTemplateClass( - TEMPL_CLASS(type)))) { + if ( + !(TYPE_CLASS(type)->flags & CLASS_FLAGS_2) && + ( + !(TYPE_CLASS(type)->flags & CLASS_FLAGS_800) || + !CTempl_InstantiateTemplateClass(TYPE_CLASS(type)) + ) + ) + { CError_Error(136, type, 0); return 0; } @@ -418,7 +386,7 @@ void CDecl_ParseDirectFuncDecl(DeclInfo *declinfo) { if (copts.cplusplus) { CDecl_ParseCPPFuncDecl(tfunc); - if (declinfo->storageclass == OBJECT_SCLASS_104 && tfunc->exspecs) + if (declinfo->storageclass == TK_TYPEDEF && tfunc->exspecs) CError_Error(264); } @@ -638,11 +606,13 @@ static Boolean CDecl_IsEnumClassTypeOrRef(Type *type) { return IS_TYPE_CLASS(type) || IS_TYPE_ENUM(type); } -#define OpMysteryValue0 0 -#define OpMysteryValue1 1 -#define OpMysteryValue2 2 -#define OpMysteryValue3 3 -#define OpMysteryValue4 4 +typedef enum OpMysteryValue { + OpMysteryValue0 = 0, + OpMysteryValue1 = 1, + OpMysteryValue2 = 2, + OpMysteryValue3 = 3, + OpMysteryValue4 = 4 +} OpMysteryValue; static Boolean CDecl_CheckOperatorType(DeclInfo *declinfo, Boolean flag) { FuncArg *args; @@ -675,7 +645,11 @@ static Boolean CDecl_CheckOperatorType(DeclInfo *declinfo, Boolean flag) { secondarg = args->next; if (secondarg) { - r27 = ((secondarg != &elipsis && !secondarg->next) != 0) ? OpMysteryValue4 : OpMysteryValue3; + //r27 = ((secondarg != &elipsis && !secondarg->next) != 0) ? OpMysteryValue2 : OpMysteryValue3; + if ((secondarg != &elipsis && !secondarg->next) != 0) + r27 = OpMysteryValue2; + else + r27 = OpMysteryValue3; if (secondarg->dexpr) { switch (declinfo->x3E) { case '(': @@ -1416,11 +1390,11 @@ void CheckDefaultArgs(FuncArg *args) { } static void CDecl_FuncRedeclCheck(Object *obj, DeclInfo *declinfo, Boolean flag) { - if (declinfo->storageclass == OBJECT_SCLASS_102 && obj->sclass != OBJECT_SCLASS_102) { + if (declinfo->storageclass == TK_STATIC && obj->sclass != TK_STATIC) { if (copts.cplusplus) CError_Error(260); else - obj->sclass = OBJECT_SCLASS_102; + obj->sclass = TK_STATIC; } obj->qual |= declinfo->qual; @@ -1460,8 +1434,7 @@ Object *CDecl_GetFunctionObject(DeclInfo *declinfo, NameSpace *nspace, Boolean * } if (nspace2->theclass) { -#line 1969 - CError_ASSERT(declinfo->name); + CError_ASSERT(1969, declinfo->name); if (!nspace2->theclass->size) CDecl_CompleteType((Type *) nspace2->theclass); if (!(list = CScope_GetLocalObject(nspace2, declinfo->name))) { @@ -1614,8 +1587,7 @@ void CDecl_TypedefDeclarator(DeclInfo *declinfo) { CError_Error(322); return; default: -#line 2156 - CError_FATAL(); + CError_FATAL(2156); } } @@ -1654,8 +1626,8 @@ void CDecl_TypedefDeclarator(DeclInfo *declinfo) { } } - if (cparamblkptr->browseOptions.recordTypedefs && declinfo->fileoffsetinfo.file->recordbrowseinfo) - CBrowse_NewTypedef(nspace, declinfo->name, declinfo->fileoffsetinfo.file, declinfo->fileoffsetinfo.tokenline, declinfo->fileoffsetinfo.tokenoffset, CPrep_BrowserFileOffset()); + if (cparamblkptr->browseOptions.recordTypedefs && declinfo->file->recordbrowseinfo) + CBrowse_NewTypedef(nspace, declinfo->name, declinfo->file, declinfo->file2, declinfo->x60, CPrep_BrowserFileOffset()); } static void CDecl_DataDeclarator(DeclInfo *declinfo, short access, Boolean flag) { @@ -1697,8 +1669,7 @@ static void CDecl_DataDeclarator(DeclInfo *declinfo, short access, Boolean flag) CError_Error(221); break; default: -#line 2281 - CError_FATAL(); + CError_FATAL(2281); } } @@ -1706,24 +1677,24 @@ static void CDecl_DataDeclarator(DeclInfo *declinfo, short access, Boolean flag) if (!flag) CDecl_CompleteType(declinfo->thetype); switch (declinfo->storageclass) { - case OBJECT_SCLASS_103: + case TK_EXTERN: if (tk == '=' || tk == '(') declinfo->storageclass = 0; break; case 0: if (CParser_IsConst(declinfo->thetype, declinfo->qual)) { - if ((!obj && !nspace->theclass) || (obj && obj->sclass != OBJECT_SCLASS_103 && !obj->nspace->theclass)) - declinfo->storageclass = OBJECT_SCLASS_102; + if ((!obj && !nspace->theclass) || (obj && obj->sclass != TK_EXTERN && !obj->nspace->theclass)) + declinfo->storageclass = TK_STATIC; } break; } } else { - if (declinfo->storageclass == OBJECT_SCLASS_103 && tk == '=') + if (declinfo->storageclass == TK_EXTERN && tk == '=') declinfo->storageclass = 0; } if (IS_TYPE_ARRAY(declinfo->thetype) && !declinfo->thetype->size && !declinfo->storageclass && tk != '=') - declinfo->storageclass = OBJECT_SCLASS_103; + declinfo->storageclass = TK_EXTERN; if (obj) { if ((!obj->type->size || !declinfo->thetype->size) && IS_TYPE_ARRAY(declinfo->thetype) && IS_TYPE_ARRAY(obj->type)) @@ -1740,8 +1711,8 @@ static void CDecl_DataDeclarator(DeclInfo *declinfo, short access, Boolean flag) CError_Error(333, obj); } - if (declinfo->storageclass != OBJECT_SCLASS_103) { - if (obj->sclass != OBJECT_SCLASS_103 && declinfo->storageclass && obj->sclass != declinfo->storageclass) + if (declinfo->storageclass != TK_EXTERN) { + if (obj->sclass != TK_EXTERN && declinfo->storageclass && obj->sclass != declinfo->storageclass) CError_Error(333, obj); if (tmpflag) { @@ -1788,15 +1759,14 @@ static void CDecl_DataDeclarator(DeclInfo *declinfo, short access, Boolean flag) CInit_InitializeData(obj); } - if (declinfo->fileoffsetinfo.file->recordbrowseinfo && obj->sclass != OBJECT_SCLASS_103) - CBrowse_NewData(obj, declinfo->fileoffsetinfo.file, declinfo->fileoffsetinfo.tokenline, declinfo->fileoffsetinfo.tokenoffset, CPrep_BrowserFileOffset()); + if (declinfo->file->recordbrowseinfo && obj->sclass != TK_EXTERN) + CBrowse_NewData(obj, declinfo->file, declinfo->file2, declinfo->x60, CPrep_BrowserFileOffset()); } else if (tk == '=') { tk = lex(); expr = CExpr_IntegralConstOrDepExpr(); if (IS_TYPE_TEMPLATE(obj->type) || !ENODE_IS(expr, EINTCONST)) { -#line 2426 - CError_ASSERT(nspace->theclass && (nspace->theclass->flags & CLASS_FLAGS_100)); - CTemplClass_RegisterObjectInit(TEMPL_CLASS(nspace->theclass), OBJ_BASE(obj), expr); + CError_ASSERT(2426, nspace->theclass && (nspace->theclass->flags & CLASS_FLAGS_100)); + CTemplClass_RegisterObjectInit(TEMPL_CLASS(nspace->theclass), obj, expr); } else if ((obj->qual & Q_CONST) && IS_TYPE_INT_OR_ENUM(obj->type)) { obj->u.data.u.intconst = expr->data.intval; obj->qual |= Q_10000 | Q_20000; @@ -1820,21 +1790,20 @@ Boolean CDecl_FunctionDeclarator(DeclInfo *declinfo, NameSpace *nspace, Boolean } if (obj->nspace == cscope_root && !strcmp(obj->name->name, "main")) { - if (obj->sclass == OBJECT_SCLASS_102 || (copts.ANSI_strict && TYPE_FUNC(obj->type)->functype != (Type *) &stsignedint)) + if (obj->sclass == TK_STATIC || (copts.ANSI_strict && TYPE_FUNC(obj->type)->functype != (Type *) &stsignedint)) CError_Error(334); - } else if (copts.require_prototypes && (pflag || declinfo->fileoffsetinfo.is_inline)) { - if (obj->sclass != OBJECT_SCLASS_102 && !(obj->qual & Q_INLINE) && !obj->nspace->is_unnamed) + } else if (copts.require_prototypes && (pflag || declinfo->x64)) { + if (obj->sclass != TK_STATIC && !(obj->qual & Q_INLINE) && !obj->nspace->is_unnamed) CError_Warning(178); } CFunc_ParseFuncDef(obj, declinfo, NULL, 0, 0, NULL); - // WARNING: WEIRD FileOffsetInfo ALERT - if (declinfo->fileoffsetinfo.file->recordbrowseinfo) + if (declinfo->file->recordbrowseinfo) CBrowse_NewFunction( obj, - declinfo->fileoffsetinfo.file, - (CPrepFileInfo *) declinfo->fileoffsetinfo.tokenline, - declinfo->fileoffsetinfo.tokenoffset, + declinfo->file, + declinfo->file2, + declinfo->x60, CPrep_BrowserFileOffset()); if (copts.cplusplus && lookahead() == ';') @@ -1851,11 +1820,9 @@ static void CDecl_ParseSpecialMember(DeclInfo *declinfo, Boolean flag) { NameSpace *r25; if (!(r28 = declinfo->x10)) { -#line 2544 - CError_ASSERT(declinfo->x14); - r28 = declinfo->x14->object; -#line 2546 - CError_ASSERT(r28->otype == OT_OBJECT); + CError_ASSERT(2544, declinfo->x14); + r28 = OBJECT(declinfo->x14->object); + CError_ASSERT(2546, r28->otype == OT_OBJECT); } if (!r28->nspace->theclass) { @@ -1900,8 +1867,7 @@ static void CDecl_ParseSpecialMember(DeclInfo *declinfo, Boolean flag) { } return; } else if (TYPE_FUNC(r28->type)->flags & FUNC_FLAGS_40) { -#line 2603 - CError_FATAL(); + CError_FATAL(2603); declinfo->thetype = TYPE_FUNC(r28->type)->functype; declinfo->qual |= TYPE_FUNC(r28->type)->qual; @@ -1967,7 +1933,7 @@ void CDecl_ScanDeclarator(DeclInfo *declinfo) { return; } - if (declinfo->storageclass && declinfo->storageclass != OBJECT_SCLASS_103) + if (declinfo->storageclass && declinfo->storageclass != TK_EXTERN) CError_Error(177); if (IS_TYPE_FUNC(declinfo->thetype)) { @@ -1983,7 +1949,7 @@ void CDecl_ScanDeclarator(DeclInfo *declinfo) { if ( (declinfo->qual & ~(Q_ALIGNED_MASK | Q_OVERLOAD | Q_20000 | Q_PASCAL | Q_VOLATILE | Q_CONST)) || - (declinfo->storageclass == OBJECT_SCLASS_104 && (declinfo->qual & ~(Q_ALIGNED_MASK | Q_REFERENCE | Q_PASCAL | Q_VOLATILE | Q_CONST))) + (declinfo->storageclass == TK_TYPEDEF && (declinfo->qual & ~(Q_ALIGNED_MASK | Q_REFERENCE | Q_PASCAL | Q_VOLATILE | Q_CONST))) ) CError_Error(176); } @@ -2000,8 +1966,7 @@ void scandeclaratorlist(DeclInfo *declinfo) { } CScope_GetScope(&savescope); -#line 2707 - CError_ASSERT(declinfo->thetype); + CError_ASSERT(2707, declinfo->thetype); r28 = 1; while (1) { @@ -2020,7 +1985,7 @@ void scandeclaratorlist(DeclInfo *declinfo) { break; } - if (declinfo->storageclass != OBJECT_SCLASS_104) { + if (declinfo->storageclass != TK_TYPEDEF) { if (IS_TYPE_FUNC(declinfo->thetype)) { if (!CDecl_FunctionDeclarator(declinfo, NULL, r28, 1)) return; @@ -2282,8 +2247,7 @@ static TypeEnum *CDecl_OldParseEnumList(TypeEnum *tenum, HashNameNode *name) { CError_Error(154); break; default: -#line 3071 - CError_FATAL(); + CError_FATAL(3071); } } else { switch (basetype->size) { @@ -2307,8 +2271,7 @@ static TypeEnum *CDecl_OldParseEnumList(TypeEnum *tenum, HashNameNode *name) { case 8: break; default: -#line 3099 - CError_FATAL(); + CError_FATAL(3099); } } @@ -2378,9 +2341,6 @@ void CDecl_ComputeUnderlyingEnumType(TypeEnum *tenum) { ObjEnumConst *oec2; Type *r26; int t; - CInt64 maximumU; - CInt64 unused; - CInt64 minimum, maximum; if (!copts.enumsalwaysint) { for (oec2 = tenum->enumlist; oec2; oec2 = oec2->next) { @@ -2389,9 +2349,9 @@ void CDecl_ComputeUnderlyingEnumType(TypeEnum *tenum) { } if (oec2) { - unused = cint64_zero; - minimum = cint64_zero; - maximum = cint64_zero; + CInt64 unused = cint64_zero; + CInt64 minimum = cint64_zero; + CInt64 maximum = cint64_zero; for (oec = tenum->enumlist; oec; oec = oec->next) { if (CInt64_IsNegative(&oec->val) && !is_unsigned(oec->type)) { if (CInt64_Less(oec->val, minimum)) @@ -2420,11 +2380,11 @@ void CDecl_ComputeUnderlyingEnumType(TypeEnum *tenum) { break; } while (1); } else { - maximumU = cint64_zero; + CInt64 val = cint64_zero; for (oec = tenum->enumlist; oec; oec = oec->next) { - if (CInt64_GreaterU(oec->val, maximumU)) - maximumU = oec->val; + if (CInt64_GreaterU(oec->val, val)) + val = oec->val; } t = 0; @@ -2435,7 +2395,7 @@ void CDecl_ComputeUnderlyingEnumType(TypeEnum *tenum) { CError_Error(154); break; } - if (CInt64_IsInURange(maximumU, r26->size)) + if (CInt64_IsInURange(val, r26->size)) break; } while (1); } @@ -2691,18 +2651,17 @@ void scanenum(DeclInfo *declinfo) { declinfo->thetype = TYPE(CDecl_ParseEnumList(NULL, name)); } - if (cparamblkptr->browseOptions.recordEnums && declinfo->fileoffsetinfo.file->recordbrowseinfo) + if (cparamblkptr->browseOptions.recordEnums && declinfo->file->recordbrowseinfo) CBrowse_NewEnum( cscope_current, TYPE_ENUM(declinfo->thetype)->enumname, - declinfo->fileoffsetinfo.file, - (CPrepFileInfo *) declinfo->fileoffsetinfo.tokenline, - declinfo->fileoffsetinfo.tokenoffset, + declinfo->file, + declinfo->file2, + declinfo->x60, CPrep_BrowserFileOffset()); return; } else { -#line 3851 - CError_ASSERT(!copts.cplusplus || tk != ';'); + CError_ASSERT(3851, !copts.cplusplus || tk != ';'); tkidentifier = name; } } @@ -2716,8 +2675,7 @@ void scanenum(DeclInfo *declinfo) { declinfo->thetype = type; return; } else { -#line 3865 - CError_ASSERT(pr.name_4); + CError_ASSERT(3865, pr.name_4); if ((tk = lex()) == '{') { declinfo->thetype = TYPE(CDecl_ParseEnumList(NULL, pr.name_4)); return; @@ -2759,7 +2717,7 @@ void CDecl_ScanStructDeclarator(BigDeclInfo *bde) { } if ((!copts.ANSI_strict || copts.c9x) && !bde->declinfo2.thetype->size && IS_TYPE_ARRAY(bde->declinfo2.thetype)) { - if (bde->declinfo2.storageclass != OBJECT_SCLASS_102 && bde->declinfo2.storageclass != OBJECT_SCLASS_104) { + if (bde->declinfo2.storageclass != TK_STATIC && bde->declinfo2.storageclass != TK_TYPEDEF) { type = TYPE_POINTER(bde->declinfo2.thetype)->target; while (IS_TYPE_ARRAY(type)) type = TYPE_POINTER(type)->target; @@ -2771,7 +2729,7 @@ void CDecl_ScanStructDeclarator(BigDeclInfo *bde) { } } } else { - if (bde->declinfo2.storageclass != OBJECT_SCLASS_102 && bde->declinfo2.storageclass != OBJECT_SCLASS_104) { + if (bde->declinfo2.storageclass != TK_STATIC && bde->declinfo2.storageclass != TK_TYPEDEF) { if (!IS_TYPE_FUNC(bde->declinfo2.thetype) && !IsCompleteType(bde->declinfo2.thetype)) return; } @@ -2885,8 +2843,7 @@ static void CDecl_LayoutStruct(TypeStruct *tstruct) { r23 = 1; if (!member->name) { -#line 4064 - CError_ASSERT(IS_TYPE_STRUCT(member->type)); + CError_ASSERT(4064, IS_TYPE_STRUCT(member->type)); innerbase = member->offset; innermember = TYPE_STRUCT(member->type)->members; r23 = 1; @@ -3076,7 +3033,7 @@ void scanstruct(DeclInfo *declinfo, short structtype) { HashNameNode *name; TypeStruct typecopy; Boolean add_to_browse; - BrowseStruct bs; + GList gl; SInt32 offset; if (copts.cplusplus) { @@ -3127,8 +3084,8 @@ void scanstruct(DeclInfo *declinfo, short structtype) { type = (Type *) CDecl_DefineStruct(NULL, structtype); } - if ((add_to_browse = cparamblkptr->browseOptions.recordClasses && declinfo->fileoffsetinfo.file->recordbrowseinfo)) - CBrowse_BeginStruct(declinfo, TYPE_STRUCT(type), &bs); + if ((add_to_browse = cparamblkptr->browseOptions.recordClasses && declinfo->file->recordbrowseinfo)) + CBrowse_BeginStruct(declinfo, TYPE_STRUCT(type), &gl); typecopy = *TYPE_STRUCT(type); tk = lex(); @@ -3137,7 +3094,7 @@ void scanstruct(DeclInfo *declinfo, short structtype) { declinfo->thetype = type; if (add_to_browse) - CBrowse_EndStruct(offset, &bs); + CBrowse_EndStruct(offset, &gl); } static void InlineFunctionObject(Object *obj, TypeClass *tclass) { @@ -3243,14 +3200,12 @@ static void CDecl_AddFunctionMember(DeclE *decle, TypeClass *tclass, DeclInfo *d declinfo->thetype = (Type *) tfunc; } else { tfunc = TYPE_METHOD(declinfo->thetype); -#line 4579 - CError_ASSERT(!tclass->sominfo); + CError_ASSERT(4579, !tclass->sominfo); } CDecl_ExtractClassExportFlags(declinfo, tclass->eflags); -#line 4597 - CError_ASSERT(cscope_current == tclass->nspace); + CError_ASSERT(4597, cscope_current == tclass->nspace); if (list) { obj = CDecl_OverloadFunctionObject(list, declinfo, &outflag, flag4 ? OverloadMode1 : OverloadMode2, 0); @@ -3491,7 +3446,7 @@ static void CDecl_ParseFriendDecl(TypeClass *tclass) { InlineFunctionObject(obj, tclass); } else { if (!obj->sclass) - obj->sclass = OBJECT_SCLASS_103; + obj->sclass = TK_EXTERN; } } } else { @@ -3535,8 +3490,7 @@ static ObjMemberVar *CDecl_InstanceDataDeclarator(DeclE *decle, TypeClass *tclas case OT_TYPETAG: break; default: -#line 4989 - CError_FATAL(); + CError_FATAL(4989); } } @@ -3628,7 +3582,7 @@ static void CDecl_ParseClassMembers(DeclE *decle, TypeClass *tclass, short mode) } } - CTempl_Parse(tclass, access); + CTempl_Parse(TEMPL_CLASS(tclass), access); tk = lex(); continue; } @@ -3716,7 +3670,7 @@ static void CDecl_ParseClassMembers(DeclE *decle, TypeClass *tclass, short mode) scandeclarator(&bde.declinfo2); if (IS_TYPE_FUNC(bde.declinfo2.thetype)) { if (r17) - bde.declinfo2.thetype = CTemplTool_ResolveMemberSelfRefs(tclass, bde.declinfo2.thetype, &bde.declinfo2.qual); + bde.declinfo2.thetype = CTemplTool_ResolveMemberSelfRefs(TEMPL_CLASS(tclass), bde.declinfo2.thetype, &bde.declinfo2.qual); if (tclass->sominfo) { if (TYPE_FUNC(bde.declinfo2.thetype)->args) CError_Error(272); @@ -3856,9 +3810,9 @@ static void CDecl_ParseClassMembers(DeclE *decle, TypeClass *tclass, short mode) after_various_things: switch (bde.declinfo.storageclass) { case 0: - case OBJECT_SCLASS_102: - case OBJECT_SCLASS_104: - case OBJECT_SCLASS_12B: + case TK_STATIC: + case TK_TYPEDEF: + case TK_MUTABLE: break; default: CError_Error(177); @@ -3869,11 +3823,11 @@ static void CDecl_ParseClassMembers(DeclE *decle, TypeClass *tclass, short mode) while (1) { CDecl_ScanStructDeclarator(&bde); if (r17) - bde.declinfo2.thetype = CTemplTool_ResolveMemberSelfRefs(tclass, bde.declinfo2.thetype, &bde.declinfo2.qual); + bde.declinfo2.thetype = CTemplTool_ResolveMemberSelfRefs(TEMPL_CLASS(tclass), bde.declinfo2.thetype, &bde.declinfo2.qual); if (bde.declinfo2.nspace) CError_Error(200); if (bde.declinfo2.x3E) { - if (bde.declinfo.storageclass == OBJECT_SCLASS_12B) + if (bde.declinfo.storageclass == TK_MUTABLE) CError_QualifierCheck(Q_MUTABLE); r19 = 0; switch (bde.declinfo2.x3E) { @@ -3888,7 +3842,7 @@ static void CDecl_ParseClassMembers(DeclE *decle, TypeClass *tclass, short mode) r19 = 1; break; default: - if (bde.declinfo2.storageclass == OBJECT_SCLASS_102) + if (bde.declinfo2.storageclass == TK_STATIC) CError_Error(193); if (tclass->sominfo) CError_Error(193); @@ -3908,11 +3862,11 @@ static void CDecl_ParseClassMembers(DeclE *decle, TypeClass *tclass, short mode) if (bde.declinfo2.name == constructor_name_node || bde.declinfo2.name == destructor_name_node) CError_Error(241); switch (bde.declinfo2.storageclass) { - case OBJECT_SCLASS_104: + case TK_TYPEDEF: CError_QualifierCheck(bde.declinfo2.qual & Q_VIRTUAL); CDecl_TypedefDeclarator(&bde.declinfo2); break; - case OBJECT_SCLASS_102: + case TK_STATIC: CError_QualifierCheck(bde.declinfo2.qual & Q_VIRTUAL); if (tclass->sominfo) CError_Error(271); @@ -3929,11 +3883,11 @@ static void CDecl_ParseClassMembers(DeclE *decle, TypeClass *tclass, short mode) } break; case 0: - case OBJECT_SCLASS_12B: + case TK_MUTABLE: if (IS_TYPE_FUNC(bde.declinfo2.thetype)) { if (bde.declinfo2.name == tclass->classname) CError_Error(241); - if (bde.declinfo.storageclass == OBJECT_SCLASS_12B) + if (bde.declinfo.storageclass == TK_MUTABLE) CError_QualifierCheck(Q_MUTABLE); bde.declinfo2.qual |= r21; CDecl_AddFunctionMember(decle, tclass, &bde.declinfo2, access, 1, 0, 1, 0); @@ -3941,7 +3895,7 @@ static void CDecl_ParseClassMembers(DeclE *decle, TypeClass *tclass, short mode) CDecl_CompleteType(bde.declinfo2.thetype); CanCreateObject(bde.declinfo2.thetype); CError_QualifierCheck(bde.declinfo2.qual & (Q_VIRTUAL | Q_INLINE)); - if (bde.declinfo2.storageclass == OBJECT_SCLASS_12B) + if (bde.declinfo2.storageclass == TK_MUTABLE) bde.declinfo2.qual |= Q_MUTABLE; CDecl_InstanceDataDeclarator(decle, tclass, bde.declinfo2.thetype, bde.declinfo2.qual, bde.declinfo2.name, access); } @@ -4236,17 +4190,14 @@ static void CDecl_ParseBaseClassList(TypeClass *tclass, short mode, Boolean is_t } } -static short getaccesstype(short a, short b, short c) { - AccessType a1 = (AccessType) a; - AccessType b1 = (AccessType) b; - AccessType c1 = (AccessType) c; - - if (a1 == ACCESSNONE || b1 == ACCESSNONE || b1 == ACCESSPRIVATE) +static short getaccesstype(AccessType a, AccessType b, AccessType c) { + if (a == ACCESSNONE || b == ACCESSNONE || b == ACCESSPRIVATE) return ACCESSNONE; - else if (c1 == ACCESSPUBLIC && a1 != ACCESSPUBLIC) + + if (c == ACCESSPUBLIC && b != ACCESSPUBLIC) return ACCESSNONE; - else - return ACCESSPUBLIC; + + return ACCESSPUBLIC; } static TypeMethod *CDecl_MakeDefaultCtorType(TypeClass *tclass) { @@ -4566,8 +4517,7 @@ static void CDecl_SetupClassLayout(DeclE *decle, TypeClass *tclass, ObjBase **ob i = TYPE_METHOD(obj->type)->x1E; if (i > 0) { -#line 6363 - CError_ASSERT((i - 1) < decle->x8 && !objbuf[(int) (i - 1)]); + CError_ASSERT(6363, (i - 1) < decle->x8 && !objbuf[(int) (i - 1)]); objbuf[(int) (i - 1)] = OBJ_BASE(obj); index++; if (obj->datatype != DVFUNC && !TYPE_METHOD(obj->type)->x26 && CClass_OverridesBaseMember(tclass, obj->name, obj)) @@ -4587,8 +4537,7 @@ static void CDecl_SetupClassLayout(DeclE *decle, TypeClass *tclass, ObjBase **ob TYPE_FUNC(obj->type)->flags &= ~FUNC_FLAGS_8; } } else { -#line 6412 - CError_ASSERT(i == 0); + CError_ASSERT(6412, i == 0); } if (!tclass->sominfo) @@ -4609,19 +4558,16 @@ static void CDecl_SetupClassLayout(DeclE *decle, TypeClass *tclass, ObjBase **ob if (!tclass->sominfo) { for (i = 0, ivar = tclass->ivars; i < decle->x8; i++) { if (!objbuf[i]) { -#line 6449 - CError_ASSERT(ivar); + CError_ASSERT(6449, ivar); objbuf[i] = OBJ_BASE(ivar); ivar = ivar->next; index++; } } -#line 6455 - CError_ASSERT(ivar == NULL); + CError_ASSERT(6455, ivar == NULL); } -#line 6458 - CError_ASSERT(index == decle->x8); + CError_ASSERT(6458, index == decle->x8); } void CDecl_CompleteClass(DeclE *decle, TypeClass *tclass) { @@ -4660,9 +4606,8 @@ TypeClass *CDecl_DefineClass(NameSpace *nspace, HashNameNode *name, TypeClass *t ObjType *objtype; if (!tclass && nspace->theclass && (nspace->theclass->flags & CLASS_FLAGS_100)) { -#line 6556 - CError_ASSERT(!flag2); - return CTemplClass_DefineNestedClass(TEMPL_CLASS(nspace->theclass), name, mode); + CError_ASSERT(6556, !flag2); + return TYPE_CLASS(CTemplClass_DefineNestedClass(TEMPL_CLASS(nspace->theclass), name, mode)); } mynspace = CScope_NewListNameSpace(name, 1); @@ -4759,7 +4704,7 @@ void CDecl_ParseClass(DeclInfo *declinfo, short mode, Boolean flag1, UInt8 class NameSpace *nspace; CScopeParseResult pr; CScopeSave scopesave; - BrowseStruct bs; + GList gl; FileOffsetInfo offsetsave; SInt32 offset; Boolean is_templ; @@ -4828,8 +4773,7 @@ void CDecl_ParseClass(DeclInfo *declinfo, short mode, Boolean flag1, UInt8 class goto tagtype_search; } -#line 6786 - CError_ASSERT(pr.name_4); + CError_ASSERT(6786, pr.name_4); tclass = CDecl_DefineClass(CScope_FindNonClassNonFunctionNS(cscope_current), pr.name_4, NULL, mode, 0, 1); tclass->eflags |= class_declspec; @@ -4865,8 +4809,7 @@ void CDecl_ParseClass(DeclInfo *declinfo, short mode, Boolean flag1, UInt8 class TEMPL_CLASS_INST(tclass)->is_specialized = 1; } -#line 6853 - CError_ASSERT(copts.align_mode >= 0 && copts.align_mode <= 14); + CError_ASSERT(6853, copts.align_mode >= 0 && copts.align_mode <= 14); tclass->eflags |= (UInt8) ((copts.align_mode + 1) << 4); if (tk == ':') @@ -4875,9 +4818,9 @@ void CDecl_ParseClass(DeclInfo *declinfo, short mode, Boolean flag1, UInt8 class CScope_SetClassDefScope(tclass, &scopesave); if (tk == '{') { tk = lex(); - if ((add_to_browse = cparamblkptr->browseOptions.recordClasses && declinfo->fileoffsetinfo.file->recordbrowseinfo)) { + if ((add_to_browse = cparamblkptr->browseOptions.recordClasses && declinfo->file->recordbrowseinfo)) { offsetsave = member_fileoffset; - CBrowse_BeginClass(declinfo, &bs); + CBrowse_BeginClass(declinfo, &gl); } CDecl_ParseClassMembers(&decle, tclass, mode); offset = CPrep_BrowserFileOffset(); @@ -4887,7 +4830,7 @@ void CDecl_ParseClass(DeclInfo *declinfo, short mode, Boolean flag1, UInt8 class member_fileoffset = offsetsave; if (flag1 && tk == ';') CPrep_BrowserFileOffset(); - CBrowse_EndClass(offset, &bs); + CBrowse_EndClass(offset, &gl); } } else { CError_Error(135); diff --git a/compiler_and_linker/unsorted/CError.c b/compiler_and_linker/unsorted/CError.c index 40e237a..a7ade45 100644 --- a/compiler_and_linker/unsorted/CError.c +++ b/compiler_and_linker/unsorted/CError.c @@ -249,7 +249,6 @@ void CError_BufferAppendTemplDepType(CErrorBuffer *eb, TypeTemplDep *type) { } void CError_BufferAppendFuncArgs(CErrorBuffer *eb, TypeFunc *tfunc, Boolean isMethod) { - // not matching - weirdness with referencing string constants FuncArg *arg; UInt32 qual; @@ -274,14 +273,14 @@ void CError_BufferAppendFuncArgs(CErrorBuffer *eb, TypeFunc *tfunc, Boolean isMe if (arg == &elipsis || arg == &oldstyle) { CError_BufferAppendString(eb, "..."); break; - } else { - CError_BufferAppendType(eb, arg->type, arg->qual); } - if (!arg->next) { + CError_BufferAppendType(eb, arg->type, arg->qual); + + if ((arg = arg->next)) CError_BufferAppendString(eb, ", "); + else break; - } } } CError_BufferAppendChar(eb, ')'); @@ -291,73 +290,73 @@ void CError_BufferAppendFuncArgs(CErrorBuffer *eb, TypeFunc *tfunc, Boolean isMe void CError_BufferAppendType(CErrorBuffer *eb, Type *ty, UInt32 qual) { // not matching - register issues + Type *scan; + Type *scan2; char buf[16]; - Type *scan, *scan2; switch (ty->type) { case TYPEVOID: CError_BufferAppendQualifier(eb, qual); CError_BufferAppendString(eb, "void"); - break; + return; case TYPEINT: case TYPEFLOAT: CError_BufferAppendQualifier(eb, qual); switch (TYPE_INTEGRAL(ty)->integral) { case IT_BOOL: CError_BufferAppendString(eb, "bool"); - break; + return; case IT_CHAR: CError_BufferAppendString(eb, "char"); - break; + return; case IT_UCHAR: CError_BufferAppendString(eb, "unsigned char"); - break; + return; case IT_SCHAR: CError_BufferAppendString(eb, "signed char"); - break; + return; case IT_WCHAR_T: CError_BufferAppendString(eb, "wchar_t"); - break; + return; case IT_SHORT: CError_BufferAppendString(eb, "short"); - break; + return; case IT_USHORT: CError_BufferAppendString(eb, "unsigned short"); - break; + return; case IT_INT: CError_BufferAppendString(eb, "int"); - break; + return; case IT_UINT: CError_BufferAppendString(eb, "unsigned int"); - break; + return; case IT_LONG: CError_BufferAppendString(eb, "long"); - break; + return; case IT_ULONG: CError_BufferAppendString(eb, "unsigned long"); - break; + return; case IT_LONGLONG: CError_BufferAppendString(eb, "long long"); - break; + return; case IT_ULONGLONG: CError_BufferAppendString(eb, "unsigned long long"); - break; + return; case IT_FLOAT: CError_BufferAppendString(eb, "float"); - break; + return; case IT_SHORTDOUBLE: CError_BufferAppendString(eb, "short double"); - break; + return; case IT_DOUBLE: CError_BufferAppendString(eb, "double"); - break; + return; case IT_LONGDOUBLE: CError_BufferAppendString(eb, "long double"); - break; + return; default: CError_FATAL(584); } - break; case TYPEENUM: CError_BufferAppendQualifier(eb, qual); CError_BufferAppendNameSpace(eb, TYPE_ENUM(ty)->nspace); @@ -365,7 +364,7 @@ void CError_BufferAppendType(CErrorBuffer *eb, Type *ty, UInt32 qual) { CError_BufferAppendString(eb, TYPE_ENUM(ty)->enumname->name); else CError_BufferAppendString(eb, "{unnamed-enum}"); - break; + return; case TYPESTRUCT: CError_BufferAppendQualifier(eb, qual); switch (TYPE_STRUCT(ty)->stype) { @@ -373,7 +372,7 @@ void CError_BufferAppendType(CErrorBuffer *eb, Type *ty, UInt32 qual) { CError_BufferAppendString(eb, "struct "); break; case STRUCT_TYPE_UNION: - CError_BufferAppendString(eb, "struct "); + CError_BufferAppendString(eb, "union "); break; case STRUCT_TYPE_4: case STRUCT_TYPE_5: @@ -392,7 +391,7 @@ void CError_BufferAppendType(CErrorBuffer *eb, Type *ty, UInt32 qual) { } if (TYPE_STRUCT(ty)->name) CError_BufferAppendString(eb, TYPE_STRUCT(ty)->name->name); - break; + return; case TYPECLASS: CError_BufferAppendQualifier(eb, qual); CError_BufferAppendNameSpace(eb, TYPE_CLASS(ty)->nspace->parent); @@ -406,7 +405,7 @@ void CError_BufferAppendType(CErrorBuffer *eb, Type *ty, UInt32 qual) { } else { CError_BufferAppendString(eb, "{unnamed-class}"); } - break; + return; case TYPEPOINTER: case TYPEMEMBERPOINTER: scan = ty; @@ -430,7 +429,7 @@ void CError_BufferAppendType(CErrorBuffer *eb, Type *ty, UInt32 qual) { CError_BufferAppendPType(eb, ty); CError_BufferAppendChar(eb, ')'); CError_BufferAppendFuncArgs(eb, TYPE_FUNC(scan), ty->type == TYPEMEMBERPOINTER); - break; + return; case TYPEARRAY: scan2 = scan; while (scan->type == TYPEARRAY) @@ -445,7 +444,7 @@ void CError_BufferAppendType(CErrorBuffer *eb, Type *ty, UInt32 qual) { CError_BufferAppendType(eb, scan, 0); CError_BufferAppendChar(eb, ' '); CError_BufferAppendPType(eb, ty); - break; + return; } break; case TYPEFUNC: @@ -455,7 +454,7 @@ void CError_BufferAppendType(CErrorBuffer *eb, Type *ty, UInt32 qual) { CError_BufferAppendType(eb, TYPE_FUNC(ty)->functype, 0); CError_BufferAppendChar(eb, ' '); CError_BufferAppendFuncArgs(eb, TYPE_FUNC(ty), 0); - break; + return; case TYPEARRAY: CError_BufferAppendQualifier(eb, qual); scan = ty; @@ -472,18 +471,18 @@ void CError_BufferAppendType(CErrorBuffer *eb, Type *ty, UInt32 qual) { CError_BufferAppendChar(eb, ']'); ty = TYPE_POINTER(ty)->target; } - break; + return; case TYPETEMPLATE: CError_BufferAppendQualifier(eb, qual); CError_BufferAppendTemplDepType(eb, TYPE_TEMPLATE(ty)); - break; + return; case TYPETEMPLDEPEXPR: CError_BufferAppendString(eb, "T"); - break; + return; case TYPEBITFIELD: sprintf(buf, "bitfield:%ld", TYPE_BITFIELD(ty)->unkB); CError_BufferAppendString(eb, buf); - break; + return; default: CError_FATAL(752); } @@ -740,56 +739,58 @@ void CError_ErrorMessageVA(int code, const char *format, va_list list, Boolean f SInt32 moddate; Type *type; UInt32 qual; + const char *p; CError_BufferInit(&eb, buf, sizeof(buf)); + p = format; do { - switch (format[0]) { + switch (p[0]) { case 0: break; case '%': - switch (format[1]) { + switch (p[1]) { case 'n': MWUnmangle(va_arg(list, const char *), unmangleBuf, sizeof(unmangleBuf)); CError_BufferAppendString(&eb, unmangleBuf); - format += 2; + p += 2; continue; case 'u': CError_BufferAppendString(&eb, va_arg(list, const char *)); - format += 2; + p += 2; continue; case 'o': CError_AppendObjectName(&eb, va_arg(list, Object *)); - format += 2; + p += 2; continue; case 'm': CError_AppendMethodName(&eb, va_arg(list, ObjCMethod *)); - format += 2; + p += 2; continue; case 't': type = va_arg(list, Type *); qual = va_arg(list, UInt32); CError_BufferAppendType(&eb, type, qual); - format += 2; + p += 2; continue; case '%': CError_BufferAppendChar(&eb, '%'); - format += 2; + p += 2; continue; case 'i': sprintf(unmangleBuf, "%ld", va_arg(list, SInt32)); CError_BufferAppendString(&eb, unmangleBuf); - format += 2; + p += 2; continue; case 'f': CError_BufferAppendString(&eb, CTool_GetPathName(va_arg(list, FSSpec *), &moddate)->name); - format += 2; + p += 2; continue; default: CError_FATAL(1174); } break; default: - CError_BufferAppendChar(&eb, *(format++)); + CError_BufferAppendChar(&eb, *(p++)); continue; } break; @@ -883,6 +884,8 @@ void CError_ErrorFuncCall(short code, NameSpaceObjectList *args, ENodeList *argN CError_BufferAppendType(&eb, argscan->node->rtype, argscan->node->flags & ENODE_FLAG_QUALS); if ((argscan = argscan->next)) CError_BufferAppendString(&eb, ", "); + else + break; } CError_BufferAppendChar(&eb, ')'); break; @@ -964,15 +967,11 @@ void CError_AbstractClassError(TypeClass *tclass) { void CError_Warning(int code, ...) { va_list va; - if (trychain) + if (trychain || copts.supress_warnings) return; - if (copts.supress_warnings) { - va_start(va, code); - } else { - va_start(va, code); - CError_VAErrorMessage(code, va, 0, 1); - } + va_start(va, code); + CError_VAErrorMessage(code, va, 0, 1); va_end(va); } diff --git a/compiler_and_linker/unsorted/CException.c b/compiler_and_linker/unsorted/CException.c index 2fdd2d3..d8a100c 100644 --- a/compiler_and_linker/unsorted/CException.c +++ b/compiler_and_linker/unsorted/CException.c @@ -25,13 +25,6 @@ typedef struct UniqueObj { SInt32 uniqueid; } UniqueObj; -typedef struct DtorTemp { - struct DtorTemp *next; - Object *object; - Object *dtor; - Object *temp; -} DtorTemp; - ExceptionAction *cexcept_dobjstack; Boolean cexcept_hasdobjects; Boolean cexcept_magic; @@ -311,7 +304,7 @@ ENode *CExcept_RegisterDestructorObject(Object *local, SInt32 offset, Object *dt cexcept_dobjstack = action; expr = create_objectrefnode(local); - dtorObject = CABI_GetDestructorObject(dtor, 1); + dtorObject = CABI_GetDestructorObject(dtor, CABIDestroy1); if (offset == 0) { action->type = EAT_DESTROYLOCAL; @@ -339,7 +332,7 @@ void CExcept_RegisterLocalArray(Statement *stmt, Object *localarray, Object *dto action->prev = cexcept_dobjstack; cexcept_dobjstack = action; - dtorObject = CABI_GetDestructorObject(dtor, 1); + dtorObject = CABI_GetDestructorObject(dtor, CABIDestroy1); action->type = EAT_DESTROYLOCALARRAY; action->data.destroy_local_array.localarray = localarray; @@ -493,10 +486,10 @@ void CExcept_RegisterMember(Statement *stmt, Object *objectptr, SInt32 offset, O if (cond == NULL) { if (isMember) { action->type = EAT_DESTROYMEMBER; - action->data.destroy_member.dtor = CABI_GetDestructorObject(dtor, 1); + action->data.destroy_member.dtor = CABI_GetDestructorObject(dtor, CABIDestroy1); } else { action->type = EAT_DESTROYBASE; - action->data.destroy_member.dtor = CABI_GetDestructorObject(dtor, 0); + action->data.destroy_member.dtor = CABI_GetDestructorObject(dtor, CABIDestroy0); } action->data.destroy_member.objectptr = objectptr; action->data.destroy_member.offset = offset; @@ -505,7 +498,7 @@ void CExcept_RegisterMember(Statement *stmt, Object *objectptr, SInt32 offset, O action->type = EAT_DESTROYMEMBERCOND; action->data.destroy_member_cond.objectptr = objectptr; action->data.destroy_member_cond.cond = cond; - action->data.destroy_member_cond.dtor = CABI_GetDestructorObject(dtor, 1); + action->data.destroy_member_cond.dtor = CABI_GetDestructorObject(dtor, CABIDestroy1); action->data.destroy_member_cond.offset = offset; } @@ -521,7 +514,7 @@ void CExcept_RegisterMemberArray(Statement *stmt, Object *objectptr, SInt32 offs action->type = EAT_DESTROYMEMBERARRAY; action->data.destroy_member_array.objectptr = objectptr; - action->data.destroy_member_array.dtor = CABI_GetDestructorObject(dtor, 1); + action->data.destroy_member_array.dtor = CABI_GetDestructorObject(dtor, CABIDestroy1); action->data.destroy_member_array.offset = offset; action->data.destroy_member_array.elements = elements; action->data.destroy_member_array.element_size = element_size; @@ -537,7 +530,7 @@ static Statement *CExcept_DestroyLocal(ExceptionAction *ea, Statement *stmt, Obj if (offset) expr = makediadicnode(expr, intconstnode(TYPE(&stunsignedlong), offset), EADD); - expr = CABI_DestroyObject(dtor, expr, 1, 1, 0); + expr = CABI_DestroyObject(dtor, expr, CABIDestroy1, 1, 0); CError_ASSERT(687, expr->type == EFUNCCALL && expr->data.funccall.funcref->type == EOBJREF); if (expr->data.funccall.funcref->data.objref->datatype == DVFUNC) @@ -565,7 +558,7 @@ static Statement *CExcept_DestroyLocalArray(ExceptionAction *ea, Statement *stmt newStmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); if (dtor) - dtorExpr = create_objectrefnode(CABI_GetDestructorObject(dtor, 1)); + dtorExpr = create_objectrefnode(CABI_GetDestructorObject(dtor, CABIDestroy1)); else dtorExpr = nullnode(); @@ -956,7 +949,7 @@ ENode *CExcept_ScanThrowExpression(void) { Xthrw_func, expr, resultExpr, - create_objectrefnode(CABI_GetDestructorObject(func, 1)), + create_objectrefnode(CABI_GetDestructorObject(func, CABIDestroy1)), NULL); } else { expr = funccallexpr( @@ -1318,7 +1311,7 @@ static ENode *CExcept_TempTrans_ETEMP(ENode *expr) { cexcept_eabefore = ea; ea->type = EAT_DESTROYLOCAL; ea->data.destroy_local.local = dtorTemp->object; - ea->data.destroy_local.dtor = CABI_GetDestructorObject(dtorTemp->dtor, 1); + ea->data.destroy_local.dtor = CABI_GetDestructorObject(dtorTemp->dtor, CABIDestroy1); ea = lalloc(sizeof(ExceptionAction)); *ea = *cexcept_eabefore; @@ -1635,7 +1628,7 @@ static ENode *CExcept_TempTransFuncCall(ENode *expr, Boolean isCond) { ea->type = EAT_DESTROYLOCALCOND; ea->data.destroy_local_cond.local = dtorTemp->object; - ea->data.destroy_local_cond.dtor = CABI_GetDestructorObject(dtorTemp->dtor, 1); + ea->data.destroy_local_cond.dtor = CABI_GetDestructorObject(dtorTemp->dtor, CABIDestroy1); ea->data.destroy_local_cond.cond = dtorTemp->temp; ea = lalloc(sizeof(ExceptionAction)); @@ -1653,7 +1646,7 @@ static ENode *CExcept_TempTransFuncCall(ENode *expr, Boolean isCond) { ea->type = EAT_DESTROYLOCAL; ea->data.destroy_local.local = dtorTemp->object; - ea->data.destroy_local.dtor = CABI_GetDestructorObject(dtorTemp->dtor, 1); + ea->data.destroy_local.dtor = CABI_GetDestructorObject(dtorTemp->dtor, CABIDestroy1); ea = lalloc(sizeof(ExceptionAction)); *ea = *cexcept_eabefore; @@ -1896,7 +1889,7 @@ static Statement *CExcept_DtorTransform(Statement *stmt) { } curStmt = CFunc_InsertStatement(ST_EXPRESSION, curStmt); - curStmt->expr = CABI_DestroyObject(dtorTemp->dtor, create_objectrefnode(dtorTemp->object), 1, 1, 0); + curStmt->expr = CABI_DestroyObject(dtorTemp->dtor, create_objectrefnode(dtorTemp->object), CABIDestroy1, 1, 0); curStmt->dobjstack = cexcept_eaafter; if (dtorTemp->temp) { diff --git a/compiler_and_linker/unsorted/CExpr.c b/compiler_and_linker/unsorted/CExpr.c index 425a004..f305fc9 100644 --- a/compiler_and_linker/unsorted/CExpr.c +++ b/compiler_and_linker/unsorted/CExpr.c @@ -3,16 +3,25 @@ #include "compiler/CClass.h" #include "compiler/CDecl.h" #include "compiler/CError.h" +#include "compiler/CException.h" #include "compiler/CInit.h" #include "compiler/CInline.h" +#include "compiler/CIRTransform.h" #include "compiler/CMachine.h" #include "compiler/CMangler.h" #include "compiler/CInt64.h" +#include "compiler/CObjC.h" +#include "compiler/CObjCModern.h" #include "compiler/CParser.h" #include "compiler/CPrep.h" #include "compiler/CPrepTokenizer.h" +#include "compiler/CRTTI.h" +#include "compiler/CSOM.h" +#include "compiler/CTemplateNew.h" +#include "compiler/CTemplateTools.h" #include "compiler/CodeGen.h" #include "compiler/CompilerTools.h" +#include "compiler/PPCError.h" #include "compiler/objects.h" #include "compiler/scopes.h" #include "compiler/templates.h" @@ -20,30 +29,6 @@ Boolean (*name_obj_check)(HashNameNode *, Object *); Boolean disallowgreaterthan; -// MOVE ME -extern ENode *CIRTrans_TransformOpAss(ENode *); -extern ENode *CTempl_MakeTemplDepExpr(ENode *, ENodeType, ENode *); -extern Boolean CTemplTool_IsTemplateArgumentDependentType(Type *type); -extern Boolean CTemplTool_IsTemplateArgumentDependentExpression(ENode *expr); -extern ENode *CSOM_MemberVarAccess(BClassList *path, ObjMemberVar *var, ENode *expr); -extern TemplArg *CTempl_ParseUncheckTemplArgs(void *a, Boolean flag); -extern Boolean CObjC_IsCompatibleType(Type *a, Type *b); -extern Type *CObjC_GetObjCType_id(Boolean flag); -extern ENode *CExcept_ScanThrowExpression(void); -extern void PPCError_Error(int code, ...); -extern ENode *CObjC_ParseSelectorExpression(void); -extern ENode *CObjC_ParseEncodeExpression(void); -extern ENode *CObjC_ParseProtocolExpression(void); -extern ENode *CObjC_ParseAtExpression(void); -extern ENode *CObjC_ParseMessageExpression(void); -extern ENode *CRTTI_Parse_const_cast(void); -extern ENode *CRTTI_Parse_dynamic_cast(void); -extern ENode *CRTTI_Parse_reinterpret_cast(void); -extern ENode *CRTTI_Parse_static_cast(void); -extern ENode *CRTTI_ParseTypeID(void); -extern Boolean CObjC_IsType_id(Type *type); -extern ENode *CObjC_CheckModernSendMessage(Type *type, ENode *expr); - // forward declarations static ENode *makeaddnode(ENode *left, ENode *right); static ENode *makesubnode(ENode *left, ENode *right); @@ -81,8 +66,7 @@ restart: expr->data.floatval = CMach_CalcFloatConvertFromInt(TYPE(&stsignedlong), cint64_zero); break; default: -#line 105 - CError_FATAL(); + CError_FATAL(105); } } } @@ -383,8 +367,7 @@ static ENode *integralpointerpromote(ENode *expr) { } else if (stunsignedint.size == 4) { type = TYPE(&stunsignedint); } else { -#line 480 - CError_FATAL(); + CError_FATAL(480); } } else { if (stsignedlong.size == 4) { @@ -392,8 +375,7 @@ static ENode *integralpointerpromote(ENode *expr) { } else if (stsignedint.size == 4) { type = TYPE(&stsignedint); } else { -#line 486 - CError_FATAL(); + CError_FATAL(486); } } } @@ -865,8 +847,7 @@ static ENode *CExpr_MemberVarAccess(BClassList *path, ObjMemberVar *var, ENode * ENode *accessnode; BClassList *varpath; -#line 1152 - CError_ASSERT(path); + CError_ASSERT(1152, path); if (TYPE_CLASS(path->type)->sominfo) return CSOM_MemberVarAccess(path, var, expr); @@ -952,8 +933,7 @@ ENode *CExpr_MakeNameLookupResultExpr(CScopeParseResult *pr) { CError_Error(0xDD); return nullnode(); default: -#line 1268 - CError_FATAL(); + CError_FATAL(1268); } } @@ -964,8 +944,7 @@ ENode *CExpr_MakeNameLookupResultExpr(CScopeParseResult *pr) { return expr; } -#line 1278 - CError_FATAL(); + CError_FATAL(1278); return NULL; } @@ -987,19 +966,16 @@ static Type *CExpr_NewPTMType(EMemberInfo *member, Object *obj) { ptm->ty1 = OBJ_MEMBER_VAR(member->list->object)->type; } else { if (!obj) { -#line 1306 - CError_ASSERT(member->list->object->otype == OT_OBJECT); + CError_ASSERT(1306, member->list->object->otype == OT_OBJECT); obj = OBJECT(member->list->object); -#line 1308 - CError_ASSERT(IS_TYPE_FUNC(obj->type)); + CError_ASSERT(1308, IS_TYPE_FUNC(obj->type)); } tmethod = galloc(sizeof(TypeMethod)); memclrw(tmethod, sizeof(TypeMethod)); *tmethod = *TYPE_METHOD(obj->type); -#line 1312 - CError_ASSERT(tmethod->args); + CError_ASSERT(1312, tmethod->args); tmethod->args = tmethod->args->next; CDecl_MakePTMFuncType(TYPE_FUNC(tmethod)); @@ -1139,8 +1115,7 @@ static ENode *CExpr_ParseNameResultExpr(CScopeParseResult *pr, ENode *expr, Bool val++; } if (act->u.enumerator.objenumconst == oec) { -#line 1521 - CError_ASSERT(expr); + CError_ASSERT(1521, expr); expr = CInline_CopyExpression(expr, CopyMode0); if (val) expr = makediadicnode(expr, intconstnode(TYPE(&stsignedlong), val), EADD); @@ -1168,8 +1143,7 @@ static ENode *CExpr_ParseNameResultExpr(CScopeParseResult *pr, ENode *expr, Bool } break; default: -#line 1552 - CError_FATAL(); + CError_FATAL(1552); } member = lalloc(sizeof(EMemberInfo)); @@ -1179,8 +1153,7 @@ static ENode *CExpr_ParseNameResultExpr(CScopeParseResult *pr, ENode *expr, Bool member->pr_1D = pr->x1D; member->isambig = pr->isambig; if ((tk = lex()) == '<' && (ta_expr = CExpr_ExplicitTemplateArgCheck(pr))) { -#line 1564 - CError_ASSERT(ENODE_IS(ta_expr, EOBJLIST)); + CError_ASSERT(1564, ENODE_IS(ta_expr, EOBJLIST)); member->list = ta_expr->data.objlist.list; member->templargs = ta_expr->data.objlist.templargs; } else { @@ -1197,8 +1170,7 @@ static ENode *CExpr_ParseNameResultExpr(CScopeParseResult *pr, ENode *expr, Bool if (pr->nsol_14) { if ((tk = lex()) == '<' && (ta_expr = CExpr_ExplicitTemplateArgCheck(pr))) { -#line 1591 - CError_ASSERT(ENODE_IS(ta_expr, EOBJLIST)); + CError_ASSERT(1591, ENODE_IS(ta_expr, EOBJLIST)); for (list = ta_expr->data.objlist.list; list; list = list->next) { if (list->object->otype == OT_OBJECT && IS_TYPE_NONSTATIC_METHOD(OBJECT(list->object)->type)) { member = lalloc(sizeof(EMemberInfo)); @@ -1290,8 +1262,7 @@ static ENode *CExpr_ParseNameResultExpr(CScopeParseResult *pr, ENode *expr, Bool return create_objectrefnode(obj); } -#line 1711 - CError_FATAL(); + CError_FATAL(1711); return NULL; } @@ -1462,8 +1433,7 @@ static SInt32 CExpr_AtomTypeID(IntegralType what) { case IT_23: return 38; case IT_24: return 39; default: -#line 1976 - CError_FATAL(); + CError_FATAL(1976); return 0; } } @@ -1734,8 +1704,7 @@ static ENode *CExpr_NewPTMFCall(void) { CError_Error(115); return nullnode(); } else { -#line 2465 - CError_FATAL(); + CError_FATAL(2465); return nullnode(); } } @@ -1770,8 +1739,7 @@ static ENode *call_ptmf(ENode *expr) { list2->node = expr->data.mfpointer.mfpointer->data.monadic; if (!copts.old_argmatch) { -#line 2568 - CError_ASSERT(IS_TYPE_POINTER_ONLY(list2->node->rtype)); + CError_ASSERT(2568, IS_TYPE_POINTER_ONLY(list2->node->rtype)); list2->node->rtype = TYPE(&void_ptr); } @@ -1938,9 +1906,8 @@ loop: goto loop; } -#line 2753 - CError_ASSERT((expr = conv.left)); - CError_ASSERT((subexpr = conv.right)); + CError_ASSERT(2753, expr = conv.left); + CError_ASSERT(2754, subexpr = conv.right); } if (IS_TYPE_POINTER(expr->rtype)) { @@ -1964,8 +1931,7 @@ loop: funcexpr = CExpr_PointerGeneration(expr); if (copts.cplusplus) { if (CExpr_CheckOperator('(', funcexpr, NULL, &conv)) { -#line 2775 - CError_ASSERT((expr = conv.x0)); + CError_ASSERT(2775, expr = conv.x0); goto loop; } if (ENODE_IS(funcexpr, EMFPOINTER)) { @@ -1996,8 +1962,7 @@ loop: expr = pointer_generation(expr); if (copts.cplusplus) { while (IS_TYPE_CLASS(expr->rtype) && CExpr_CheckOperator(TK_ARROW, expr, NULL, &conv)) { -#line 2810 - CError_ASSERT((subexpr = conv.x0)); + CError_ASSERT(2810, subexpr = conv.x0); expr = pointer_generation(subexpr); } } @@ -2020,7 +1985,7 @@ loop: expr = pointer_generation(expr); if (IS_TYPE_CLASS(expr->rtype)) { CDecl_CompleteType(expr->rtype); - if (TYPE_CLASS(expr->rtype)->objcinfo && copts.cplusplus && (subexpr = CObjC_CheckModernSendMessage(expr->rtype, expr))) + if (TYPE_CLASS(expr->rtype)->objcinfo && copts.cplusplus && (subexpr = CObjC_CheckModernSendMessage(TYPE_CLASS(expr->rtype), expr))) return subexpr; if (!(TYPE_CLASS(expr->rtype)->flags & CLASS_FLAGS_2)) @@ -2100,8 +2065,7 @@ loop: tk = lex(); goto loop; } -#line 2952 - CError_ASSERT((tmp = conv.left)); + CError_ASSERT(2952, tmp = conv.left); } tmp = CExpr_LValue(tmp, 1, 1); if (tmp->rtype == TYPE(&stbool)) { @@ -2121,8 +2085,7 @@ loop: tk = lex(); goto loop; } -#line 2976 - CError_ASSERT((tmp = conv.left)); + CError_ASSERT(2976, tmp = conv.left); } tmp = CExpr_LValue(tmp, 1, 1); checkadditive(tmp); @@ -2320,8 +2283,7 @@ static ENode *CExpr_MakeStaticMemberList(NameSpaceObjectList *list) { static ENode *CExpr_MakePTDM(ENode *expr) { ENode *result; -#line 3414 - CError_ASSERT(ENODE_IS(expr, EMEMBER) && expr->data.emember->list->object->otype == OT_MEMBERVAR); + CError_ASSERT(3414, ENODE_IS(expr, EMEMBER) && expr->data.emember->list->object->otype == OT_MEMBERVAR); result = nullnode(); result->rtype = CExpr_NewPTMType(expr->data.emember, NULL); @@ -2338,8 +2300,7 @@ ENode *getpointertomemberfunc(ENode *expr, Type *type, Boolean flag) { OLinkList *olist; SInt32 data[3]; -#line 3442 - CError_ASSERT(ENODE_IS(expr, EMEMBER)); + CError_ASSERT(3442, ENODE_IS(expr, EMEMBER)); if (expr->data.emember->expr && !copts.cpp_extensions) CError_Error(141); @@ -2378,8 +2339,7 @@ ENode *getpointertomemberfunc(ENode *expr, Type *type, Boolean flag) { while (obj->datatype == DALIAS) obj = obj->u.alias.object; -#line 3503 - CError_ASSERT(obj->otype == OT_OBJECT && IS_TYPE_NONSTATIC_METHOD(obj->type)); + CError_ASSERT(3503, obj->otype == OT_OBJECT && IS_TYPE_NONSTATIC_METHOD(obj->type)); if (TYPE_FUNC(obj->type)->flags & FUNC_FLAGS_100000) CError_Error(190); @@ -2414,8 +2374,7 @@ ENode *getpointertomemberfunc(ENode *expr, Type *type, Boolean flag) { } static ENode *getpointertomember(ENode *expr) { -#line 3554 - CError_ASSERT(ENODE_IS(expr, EMEMBER)); + CError_ASSERT(3554, ENODE_IS(expr, EMEMBER)); if (expr->data.emember->expr) CError_Error(141); @@ -2442,8 +2401,7 @@ ENode *CExpr_New_ELOGNOT_Node(ENode *input) { if (copts.cplusplus && CExpr_CheckOperator('!', expr, NULL, &conv)) { if ((input = conv.x0)) return input; -#line 3593 - CError_ASSERT((expr = conv.left)); + CError_ASSERT(3593, expr = conv.left); } switch (expr->rtype->type) { @@ -2489,8 +2447,7 @@ ENode *CExpr_New_EMONMIN_Node(ENode *input) { if (copts.cplusplus && CExpr_CheckOperator('-', expr, NULL, &conv)) { if ((input = conv.x0)) return input; -#line 3652 - CError_ASSERT((expr = conv.left)); + CError_ASSERT(3652, expr = conv.left); } switch (expr->rtype->type) { @@ -2525,8 +2482,7 @@ ENode *CExpr_New_EBINNOT_Node(ENode *input) { if (copts.cplusplus && CExpr_CheckOperator('~', expr, NULL, &conv)) { if ((input = conv.x0)) return input; -#line 3702 - CError_ASSERT((expr = conv.left)); + CError_ASSERT(3702, expr = conv.left); } expr = integralpromote(expr); @@ -2566,8 +2522,7 @@ ENode *unary_expression(void) { if (CExpr_CheckOperator(TK_INCREMENT, expr, NULL, &conv)) { if (conv.x0) return conv.x0; -#line 3748 - CError_ASSERT((expr = conv.left)); + CError_ASSERT(3748, expr = conv.left); } } else { expr = pointer_generation(unary_expression()); @@ -2589,8 +2544,7 @@ ENode *unary_expression(void) { if (CExpr_CheckOperator(TK_DECREMENT, expr, NULL, &conv)) { if (conv.x0) return conv.x0; -#line 3776 - CError_ASSERT((expr = conv.left)); + CError_ASSERT(3776, expr = conv.left); } } else { expr = pointer_generation(unary_expression()); @@ -2614,8 +2568,7 @@ ENode *unary_expression(void) { } if (CExpr_CheckOperator('&', expr, NULL, &conv)) { -#line 3809 - CError_ASSERT(conv.x0); + CError_ASSERT(3809, conv.x0); return conv.x0; } } else { @@ -2642,8 +2595,7 @@ ENode *unary_expression(void) { if (copts.cplusplus && CExpr_CheckOperator('*', expr, NULL, &conv)) { if (conv.x0) return conv.x0; -#line 3840 - CError_ASSERT((expr = conv.left)); + CError_ASSERT(3840, expr = conv.left); } if (!IS_TYPE_POINTER(expr->rtype)) { @@ -2661,8 +2613,7 @@ ENode *unary_expression(void) { if (copts.cplusplus && CExpr_CheckOperator('+', expr, NULL, &conv)) { if (conv.x0) return conv.x0; -#line 3852 - CError_ASSERT((expr = conv.left)); + CError_ASSERT(3852, expr = conv.left); } switch (expr->rtype->type) { @@ -2761,10 +2712,8 @@ ENode *PointerToMemberCast(ENode *expr, TypeMemberPointer *tm1, TypeMemberPointe CInt64 pathoffset64; ENode *tmp; -#line 3984 - CError_ASSERT(IS_TYPE_CLASS(tm1->ty2)); -#line 3985 - CError_ASSERT(IS_TYPE_CLASS(tm2->ty2)); + CError_ASSERT(3984, IS_TYPE_CLASS(tm1->ty2)); + CError_ASSERT(3985, IS_TYPE_CLASS(tm2->ty2)); if (tm1->ty2 == tm2->ty2) { expr->rtype = TYPE(tm2); @@ -3113,8 +3062,7 @@ restart: right = pointer_generation(cast_expression()); if (CExpr_CheckOperator(TK_ARROW_STAR, left, right, &conv)) { -#line 4457 - CError_ASSERT((left = conv.x0)); + CError_ASSERT(4457, left = conv.x0); goto restart; } @@ -3192,8 +3140,7 @@ restart: left = checkreference(left); goto restart; } else { -#line 4535 - CError_ASSERT(ENODE_IS(right, EINDIRECT)); + CError_ASSERT(4535, ENODE_IS(right, EINDIRECT)); tmp = lalloc(sizeof(ENode)); tmp->type = EMFPOINTER; tmp->cost = 4; @@ -3219,9 +3166,8 @@ ENode *CExpr_New_EMUL_Node(ENode *left, ENode *right) { if (copts.cplusplus && CExpr_CheckOperator('*', left, right, &conv)) { if (conv.x0) return conv.x0; -#line 4566 - CError_ASSERT((left = conv.left)); - CError_ASSERT((right = conv.right)); + CError_ASSERT(4566, left = conv.left); + CError_ASSERT(4567, right = conv.right); } return makemultnode(left, right); @@ -3238,9 +3184,8 @@ ENode *CExpr_New_EDIV_Node(ENode *left, ENode *right, Boolean no_warning) { if (copts.cplusplus && CExpr_CheckOperator('/', left, right, &conv)) { if (conv.x0) return conv.x0; -#line 4592 - CError_ASSERT((left = conv.left)); - CError_ASSERT((right = conv.right)); + CError_ASSERT(4592, left = conv.left); + CError_ASSERT(4593, right = conv.right); } return makedivnode(left, right, no_warning); @@ -3257,9 +3202,8 @@ ENode *CExpr_New_EMODULO_Node(ENode *left, ENode *right, Boolean no_warning) { if (copts.cplusplus && CExpr_CheckOperator('%', left, right, &conv)) { if (conv.x0) return conv.x0; -#line 4618 - CError_ASSERT((left = conv.left)); - CError_ASSERT((right = conv.right)); + CError_ASSERT(4618, left = conv.left); + CError_ASSERT(4619, right = conv.right); } left = integralpromote(left); @@ -3300,9 +3244,8 @@ ENode *CExpr_New_EADD_Node(ENode *left, ENode *right) { if (copts.cplusplus && CExpr_CheckOperator('+', left, right, &conv)) { if (conv.x0) return conv.x0; -#line 4665 - CError_ASSERT((left = conv.left)); - CError_ASSERT((right = conv.right)); + CError_ASSERT(4665, left = conv.left); + CError_ASSERT(4666, right = conv.right); } return makeaddnode(left, right); @@ -3319,9 +3262,8 @@ ENode *CExpr_New_ESUB_Node(ENode *left, ENode *right) { if (copts.cplusplus && CExpr_CheckOperator('-', left, right, &conv)) { if (conv.x0) return conv.x0; -#line 4690 - CError_ASSERT((left = conv.left)); - CError_ASSERT((right = conv.right)); + CError_ASSERT(4690, left = conv.left); + CError_ASSERT(4691, right = conv.right); } return makesubnode(left, right); @@ -3338,9 +3280,8 @@ ENode *CExpr_New_ESHL_Node(ENode *left, ENode *right) { if (copts.cplusplus && CExpr_CheckOperator(TK_SHL, left, right, &conv)) { if (conv.x0) return conv.x0; -#line 4715 - CError_ASSERT((left = conv.left)); - CError_ASSERT((right = conv.right)); + CError_ASSERT(4715, left = conv.left); + CError_ASSERT(4716, right = conv.right); } left = integralpromote(left); @@ -3369,9 +3310,8 @@ ENode *CExpr_New_ESHR_Node(ENode *left, ENode *right) { if (copts.cplusplus && CExpr_CheckOperator(TK_SHR, left, right, &conv)) { if (conv.x0) return conv.x0; -#line 4752 - CError_ASSERT((left = conv.left)); - CError_ASSERT((right = conv.right)); + CError_ASSERT(4752, left = conv.left); + CError_ASSERT(4753, right = conv.right); } left = integralpromote(left); @@ -3421,14 +3361,12 @@ static ENode *pointercompare(ENodeType nt, ENode *left, ENode *right) { if (IS_TYPE_INT(ltype)) { if (!(ENODE_IS(left, EINTCONST) && CInt64_IsZero(&left->data.intval))) CError_Error(144); -#line 4847 - CError_ASSERT(IS_TYPE_POINTER_ONLY(rtype)); + CError_ASSERT(4847, IS_TYPE_POINTER_ONLY(rtype)); left->rtype = TYPE(&stunsignedlong); } else if (IS_TYPE_INT(rtype)) { if (!(ENODE_IS(right, EINTCONST) && CInt64_IsZero(&right->data.intval))) CError_Error(144); -#line 4855 - CError_ASSERT(IS_TYPE_POINTER_ONLY(ltype)); + CError_ASSERT(4855, IS_TYPE_POINTER_ONLY(ltype)); right->rtype = TYPE(&stunsignedlong); } else if (!is_typeequal(ltype, rtype)) { CError_Error(245, left->rtype, ENODE_QUALS(left), right->rtype, ENODE_QUALS(right)); @@ -3473,9 +3411,8 @@ ENode *CExpr_New_ELESS_Node(ENode *left, ENode *right) { if (copts.cplusplus && CExpr_CheckOperator('<', left, right, &conv)) { if (conv.x0) return conv.x0; -#line 4929 - CError_ASSERT((left = conv.left)); - CError_ASSERT((right = conv.right)); + CError_ASSERT(4929, left = conv.left); + CError_ASSERT(4930, right = conv.right); } if (IS_TYPE_POINTER(left->rtype) || IS_TYPE_POINTER(right->rtype)) @@ -3507,9 +3444,8 @@ ENode *CExpr_New_ELESSEQU_Node(ENode *left, ENode *right) { if (copts.cplusplus && CExpr_CheckOperator(TK_LESS_EQUAL, left, right, &conv)) { if (conv.x0) return conv.x0; -#line 4976 - CError_ASSERT((left = conv.left)); - CError_ASSERT((right = conv.right)); + CError_ASSERT(4976, left = conv.left); + CError_ASSERT(4977, right = conv.right); } if (IS_TYPE_POINTER(left->rtype) || IS_TYPE_POINTER(right->rtype)) @@ -3541,9 +3477,8 @@ ENode *CExpr_New_EGREATER_Node(ENode *left, ENode *right) { if (copts.cplusplus && CExpr_CheckOperator('>', left, right, &conv)) { if (conv.x0) return conv.x0; -#line 5023 - CError_ASSERT((left = conv.left)); - CError_ASSERT((right = conv.right)); + CError_ASSERT(5023, left = conv.left); + CError_ASSERT(5024, right = conv.right); } if (IS_TYPE_POINTER(left->rtype) || IS_TYPE_POINTER(right->rtype)) @@ -3575,9 +3510,8 @@ ENode *CExpr_New_EGREATEREQU_Node(ENode *left, ENode *right) { if (copts.cplusplus && CExpr_CheckOperator(TK_GREATER_EQUAL, left, right, &conv)) { if (conv.x0) return conv.x0; -#line 5070 - CError_ASSERT((left = conv.left)); - CError_ASSERT((right = conv.right)); + CError_ASSERT(5070, left = conv.left); + CError_ASSERT(5071, right = conv.right); } if (IS_TYPE_POINTER(left->rtype) || IS_TYPE_POINTER(right->rtype)) @@ -3664,9 +3598,8 @@ ENode *CExpr_New_EEQU_Node(ENode *left, ENode *right) { if (copts.cplusplus && CExpr_CheckOperator(TK_LOGICAL_EQ, left, right, &conv)) { if (conv.x0) return conv.x0; -#line 5201 - CError_ASSERT((left = conv.left)); - CError_ASSERT((right = conv.right)); + CError_ASSERT(5201, left = conv.left); + CError_ASSERT(5202, right = conv.right); } if (IS_TYPE_POINTER(left->rtype) || IS_TYPE_POINTER(right->rtype)) @@ -3702,9 +3635,8 @@ ENode *CExpr_New_ENOTEQU_Node(ENode *left, ENode *right) { if (copts.cplusplus && CExpr_CheckOperator(TK_LOGICAL_NE, left, right, &conv)) { if (conv.x0) return conv.x0; -#line 5261 - CError_ASSERT((left = conv.left)); - CError_ASSERT((right = conv.right)); + CError_ASSERT(5261, left = conv.left); + CError_ASSERT(5262, right = conv.right); } if (IS_TYPE_POINTER(left->rtype) || IS_TYPE_POINTER(right->rtype)) @@ -3739,9 +3671,8 @@ ENode *CExpr_New_EAND_Node(ENode *left, ENode *right) { if (copts.cplusplus && CExpr_CheckOperator('&', left, right, &conv)) { if (conv.x0) return conv.x0; -#line 5321 - CError_ASSERT((left = conv.left)); - CError_ASSERT((right = conv.right)); + CError_ASSERT(5321, left = conv.left); + CError_ASSERT(5322, right = conv.right); } left = integralpromote(left); @@ -3774,9 +3705,8 @@ ENode *CExpr_New_EXOR_Node(ENode *left, ENode *right) { if (copts.cplusplus && CExpr_CheckOperator('^', left, right, &conv)) { if (conv.x0) return conv.x0; -#line 5360 - CError_ASSERT((left = conv.left)); - CError_ASSERT((right = conv.right)); + CError_ASSERT(5360, left = conv.left); + CError_ASSERT(5361, right = conv.right); } left = integralpromote(left); @@ -3809,9 +3739,8 @@ ENode *CExpr_New_EOR_Node(ENode *left, ENode *right) { if (copts.cplusplus && CExpr_CheckOperator('|', left, right, &conv)) { if (conv.x0) return conv.x0; -#line 5399 - CError_ASSERT((left = conv.left)); - CError_ASSERT((right = conv.right)); + CError_ASSERT(5399, left = conv.left); + CError_ASSERT(5400, right = conv.right); } left = integralpromote(left); @@ -3844,9 +3773,8 @@ ENode *CExpr_New_ELAND_Node(ENode *left, ENode *right) { if (copts.cplusplus && CExpr_CheckOperator(TK_LOGICAL_AND, left, right, &conv)) { if (conv.x0) return conv.x0; -#line 5438 - CError_ASSERT((left = conv.left)); - CError_ASSERT((right = conv.right)); + CError_ASSERT(5438, left = conv.left); + CError_ASSERT(5439, right = conv.right); } switch (left->rtype->type) { @@ -3930,9 +3858,8 @@ ENode *CExpr_New_ELOR_Node(ENode *left, ENode *right) { if (copts.cplusplus && CExpr_CheckOperator(TK_LOGICAL_OR, left, right, &conv)) { if (conv.x0) return conv.x0; -#line 5543 - CError_ASSERT((left = conv.left)); - CError_ASSERT((right = conv.right)); + CError_ASSERT(5543, left = conv.left); + CError_ASSERT(5544, right = conv.right); } switch (left->rtype->type) { @@ -4006,8 +3933,7 @@ ENode *CExpr_New_ELOR_Node(ENode *left, ENode *right) { ENode *CExpr_NewDyadicNode(ENode *left, ENodeType nt, ENode *right) { switch (nt) { default: -#line 5642 - CError_FATAL(); + CError_FATAL(5642); case EADD: return CExpr_New_EADD_Node(left, right); case ESUB: return CExpr_New_ESUB_Node(left, right); case EMUL: return CExpr_New_EMUL_Node(left, right); @@ -4266,8 +4192,7 @@ ENode *CExpr_New_ECOND_Node(ENode *cond, ENode *expr1, ENode *expr2) { if ((IS_TYPE_CLASS(expr1->rtype) || IS_TYPE_CLASS(expr2->rtype)) && !is_typesame(expr1->rtype, expr2->rtype)) { if (!copts.old_argmatch) { if (CExpr_CondOperatorMatch(expr1, expr2, &conv)) { -#line 6246 - CError_ASSERT(!conv.x0); + CError_ASSERT(6246, !conv.x0); expr1 = conv.left; expr2 = conv.right; } else if (CExpr_CanImplicitlyConvert(expr1, expr2->rtype, ENODE_QUALS(expr2))) { @@ -4289,8 +4214,7 @@ ENode *CExpr_New_ECOND_Node(ENode *cond, ENode *expr1, ENode *expr2) { args->next->next = NULL; if (CExpr_CheckOperatorConversion(':', expr1, expr2, args, &conv)) { -#line 6274 - CError_ASSERT(!conv.x0); + CError_ASSERT(6274, !conv.x0); expr1 = conv.left; expr2 = conv.right; } @@ -4479,8 +4403,7 @@ static ENode *makeassignmentnode(ENode *left, ENodeType nt, short token) { if (!conv.x0) { if (nt == EASS) goto continue_anyway; -#line 6531 - CError_FATAL(); + CError_FATAL(6531); } return conv.x0; } @@ -4553,11 +4476,9 @@ continue_anyway: case 1: if ((args = args->next)) break; -#line 6625 - CError_FATAL(); + CError_FATAL(6625); default: -#line 6626 - CError_FATAL(); + CError_FATAL(6626); } if (ENODE_IS(args->node, ETEMP)) { if (!(IS_TYPE_CLASS(left->rtype) && CClass_Destructor(TYPE_CLASS(left->rtype)))) { @@ -4583,8 +4504,7 @@ static ENode *makepassignmentnode(ENode *left, ENodeType nt, short token) { tk = lex(); right = pointer_generation(assignment_expression()); if (CExpr_CheckOperator(token, left, right, &conv)) { -#line 6669 - CError_ASSERT(conv.x0); + CError_ASSERT(6669, conv.x0); return conv.x0; } left = CExpr_LValue(left, 1, 1); @@ -4652,8 +4572,7 @@ static ENode *makemulassignmentnode(ENode *left, ENodeType nt, short token) { tk = lex(); right = pointer_generation(assignment_expression()); if (CExpr_CheckOperator(token, left, right, &conv)) { -#line 6753 - CError_ASSERT(conv.x0); + CError_ASSERT(6753, conv.x0); return conv.x0; } if (!IS_TYPE_INT(left->rtype) && !(IS_TYPE_FLOAT(left->rtype) && nt != EMODASS)) { @@ -4865,8 +4784,7 @@ static Boolean CExpr_HasSideEffect(ENode *expr) { case EINSTRUCTION: return 1; default: -#line 7056 - CError_FATAL(); + CError_FATAL(7056); return 0; } } @@ -4911,11 +4829,9 @@ void CExpr_CheckUnusedExpression(ENode *expr) { case 1: if ((arg = arg->next)) break; -#line 7110 - CError_FATAL(); + CError_FATAL(7110); default: -#line 7111 - CError_FATAL(); + CError_FATAL(7111); } if (!ENODE_IS(arg->node, ETEMP)) @@ -4938,8 +4854,7 @@ ENode *s_expression(void) { right = pointer_generation(assignment_expression()); if (copts.cplusplus && CExpr_CheckOperator(',', left, right, &conv)) { -#line 7143 - CError_ASSERT((left = conv.x0)); + CError_ASSERT(7143, left = conv.x0); } else { CExpr_CheckUnusedExpression(left); left = makecommaexpression(left, right); @@ -4986,8 +4901,7 @@ ENode *CExpr_IntegralConstOrDepExpr(void) { expr->rtype = TYPE_ENUM(expr->rtype)->enumtype; return expr; default: -#line 7209 - CError_FATAL(); + CError_FATAL(7209); } } diff --git a/compiler_and_linker/unsorted/CExpr2.c b/compiler_and_linker/unsorted/CExpr2.c index 67f4fb7..e2284d7 100644 --- a/compiler_and_linker/unsorted/CExpr2.c +++ b/compiler_and_linker/unsorted/CExpr2.c @@ -9,9 +9,14 @@ #include "compiler/CInline.h" #include "compiler/CMachine.h" #include "compiler/CMangler.h" +#include "compiler/CObjC.h" +#include "compiler/CObjCModern.h" #include "compiler/CParser.h" #include "compiler/CPrepTokenizer.h" #include "compiler/CScope.h" +#include "compiler/CSOM.h" +#include "compiler/CTemplateFunc.h" +#include "compiler/CTemplateTools.h" #include "compiler/CodeGen.h" #include "compiler/CompilerTools.h" #include "compiler/enode.h" @@ -28,21 +33,6 @@ #define va_arg(ap, type) (*(((type *) (ap = (char *)((((unsigned long)ap + __builtin_align(type) - 1) & ~(__builtin_align(type) - 1) ) + sizeof(type)))) - 1)) #endif -// TODO MOVE ME -extern ENode *CObjC_New(TypeClass *tclass); -extern Boolean CObjC_IsType_id(Type *type); -extern ENode *CObjC_Delete(TypeClass *tclass, ENode *expr); -extern ENode *CSOM_New(TypeClass *tclass); -extern ENode *CSOM_Delete(TypeClass *tclass, ENode *expr); -extern ENode *CSOM_EnvCheck(ENode *, ENodeList *); -extern ENode *CSOM_MethodAccess(BClassList *, Object *, Boolean); -extern Boolean CTemplTool_IsTemplateArgumentDependentExpression(ENode *expr); -extern ENode *CTemplTool_DeduceDefaultArg(Object *func, ENode *expr); -extern Boolean CTempl_CanDeduceFunc(Object *func, TypeFunc *tfunc, TemplArg *templargs); -extern void CTempl_FuncMatch(NameSpaceObjectList *nsol, TemplArg *templargs, ENodeList *argexprs, Match13 *match, ENode *expr); -extern TemplFuncInstance *CTempl_DeduceFunc(Object *func, TypeFunc *tfunc, TemplArg *templargs, Object *anotherobj, Boolean flag); -extern Boolean CObjC_IsCompatibleType(Type *a, Type *b); - ENode *assign_node; Boolean temp_reference_init; static SInt32 assign_value; // type? @@ -172,8 +162,7 @@ restart: CExpr_RecSearchExprTree(expr->data.itc.result); return; default: -#line 128 - CError_FATAL(); + CError_FATAL(128); } } @@ -296,8 +285,7 @@ static ENode *CExpr_RecSearchExprTreeReplace(ENode *expr) { expr->data.cond.expr2 = CExpr_RecSearchExprTreeReplace(expr->data.cond.expr2); return expr; default: -#line 220 - CError_FATAL(); + CError_FATAL(220); return NULL; } } @@ -557,13 +545,13 @@ ENode *CExpr_NewETEMPNode(Type *type, Boolean assign_id) { static ENode *CExpr_DerefETEMPCopy(ENode *expr) { ENode *copy; -#line 636 - CError_ASSERT(expr->rtype->type == TYPEPOINTER); + CError_ASSERT(636, IS_TYPE_POINTER_ONLY(expr->rtype)); copy = lalloc(sizeof(ENode)); *copy = *expr; copy = makemonadicnode(copy, EINDIRECT); copy->rtype = TYPE_POINTER(copy->rtype)->target; + return copy; } ENode *CExpr_GetETEMPCopy(ENode *expr) { @@ -682,8 +670,7 @@ void CExpr_ArithmeticConversion(ENode **left, ENode **right) { if ((*left)->rtype == (Type *) &stsignedlong) { *left = promote(*left, (Type *) &stunsignedlong); } else { -#line 838 - CError_ASSERT((*left)->rtype == (Type *) &stsignedlonglong); + CError_ASSERT(838, (*left)->rtype == (Type *) &stsignedlonglong); *left = promote(*left, (Type *) &stunsignedlonglong); } } @@ -742,14 +729,13 @@ static ENode *CExpr_GetEA(ENode *expr) { } ENode *CExpr_TempModifyExpr(ENode *expr) { - // register issues Type *type; - ENode *tempnode; - ENode *eanode; - ENode *assnode2; ENode *left; ENode *right; - ENode *work; + ENode *eanode; + ENode *tempnode; + ENode *indnode; + ENode *truenode; type = expr->rtype; tempnode = CExpr_NewETEMPNode(type, 1); @@ -759,23 +745,24 @@ ENode *CExpr_TempModifyExpr(ENode *expr) { return expr; } + // tempnode = expr left = makemonadicnode(tempnode, EINDIRECT); left->rtype = type; - work = makediadicnode(left, expr, EASS); + left = makediadicnode(left, expr, EASS); - left = makemonadicnode(eanode, EINDIRECT); - left->rtype = type; - right = nullnode(); - right->rtype = (Type *) &stbool; - CInt64_SetLong(&right->data.intval, 1); - assnode2 = makediadicnode(left, right, EASS); + // eanode = true + indnode = makemonadicnode(eanode, EINDIRECT); + indnode->rtype = type; + truenode = nullnode(); + truenode->rtype = (Type *) &stbool; + CInt64_SetLong(&truenode->data.intval, 1); + right = makediadicnode(indnode, truenode, EASS); - work = makediadicnode(work, assnode2, ECOMMA); - right = makemonadicnode(tempnode, EINDIRECT); - right->rtype = type; - work = makediadicnode(work, right, ECOMMA); + expr = makediadicnode(left, right, ECOMMA); - return work; + indnode = makemonadicnode(tempnode, EINDIRECT); + indnode->rtype = type; + return makediadicnode(expr, indnode, ECOMMA); } Boolean CExpr_IsLValue(ENode *expr) { @@ -924,7 +911,7 @@ loop: ENode *CExpr_MakeObjRefNode(Object *obj, Boolean flag) { ENode *expr; - if (obj->sclass == OBJECT_SCLASS_104) { + if (obj->sclass == TK_TYPEDEF) { CError_Error(141); return intconstnode((Type *) &void_ptr, 0); } @@ -978,16 +965,20 @@ ENode *CExpr_IsTempConstruction(ENode *expr, Type *type, ENode **resultexpr) { ENode *funccall; ENode *funcref; - if (!ENODE_IS(expr, EINDIRECT) || expr->rtype != type || !ENODE_IS((funccall = expr->data.monadic), EFUNCCALL) || !(args = funccall->data.funccall.args)) + if ( + !ENODE_IS(expr, EINDIRECT) || + expr->rtype != type || + !ENODE_IS((funccall = expr->data.monadic), EFUNCCALL) || + !(args = funccall->data.funccall.args) + ) return NULL; if (!ENODE_IS((funcref = funccall->data.funccall.funcref), EOBJREF) || !CClass_IsConstructor(funcref->data.objref)) { if (expr->data.monadic->data.funccall.functype->functype != type) return NULL; - if (CABI_GetStructResultArgumentIndex() == 1) { + if (CABI_GetStructResultArgumentIndex(expr->data.monadic->data.funccall.functype) == 1) { args = args->next; -#line 1277 - CError_ASSERT(args); + CError_ASSERT(1277, args); } } @@ -1040,8 +1031,7 @@ ENode *funccallexpr(Object *func, ENode *arg1, ENode *arg2, ENode *arg3, ENode * ENodeList *list; tfunc = TYPE_FUNC(func->type); -#line 1411 - CError_ASSERT(IS_TYPE_FUNC(tfunc)); + CError_ASSERT(1411, IS_TYPE_FUNC(tfunc)); expr = lalloc(sizeof(ENode)); expr->type = EFUNCCALL; @@ -1084,8 +1074,7 @@ ENode *CExpr_FuncCallSix(Object *func, ENode *arg1, ENode *arg2, ENode *arg3, EN ENodeList *list; tfunc = TYPE_FUNC(func->type); -#line 1460 - CError_ASSERT(IS_TYPE_FUNC(tfunc)); + CError_ASSERT(1460, IS_TYPE_FUNC(tfunc)); expr = lalloc(sizeof(ENode)); expr->type = EFUNCCALL; @@ -1134,8 +1123,7 @@ static void CExpr_CalcStdAssign(short checkresult, Match5 *match, Type *t1, UInt match->x6 += assign_value; break; default: -#line 1504 - CError_FATAL(); + CError_FATAL(1504); } if (flag || (IS_TYPE_POINTER_ONLY(t2) && (IS_TYPE_POINTER_ONLY(t1) || IS_TYPEPOINTER_REFERENCE(TYPE_POINTER(t2))) != 0)) { @@ -1197,8 +1185,7 @@ Boolean CExpr_MatchAssign(Type *type, UInt32 qual, ENode *expr, Match13 *match) match->match5.x8 += user_std_match.x8; break; default: -#line 1585 - CError_FATAL(); + CError_FATAL(1585); } if (IS_TYPE_POINTER_ONLY(type)) @@ -1234,7 +1221,7 @@ static short CExpr2_MemberPointerConversion(Type *type, ENode *expr, Boolean fla newnode = lalloc(sizeof(ENode)); *newnode = *expr; if (!IS_TYPE_MEMBERPOINTER(newnode->rtype)) { - newnode = CExpr_MemberPointerConversion(newnode, type, flag1); + newnode = CExpr_MemberPointerConversion(newnode, TYPE_MEMBER_POINTER(type), flag1); if (iscpp_typeequal(newnode->rtype, type)) { if (flag1) assign_node = newnode; @@ -1243,10 +1230,8 @@ static short CExpr2_MemberPointerConversion(Type *type, ENode *expr, Boolean fla } if (IS_TYPE_MEMBERPOINTER(newnode->rtype)) { -#line 1656 - CError_ASSERT(IS_TYPE_CLASS(TYPE_MEMBER_POINTER(type)->ty2)); -#line 1657 - CError_ASSERT(IS_TYPE_CLASS(TYPE_MEMBER_POINTER(newnode->rtype)->ty2)); + CError_ASSERT(1656, IS_TYPE_CLASS(TYPE_MEMBER_POINTER(type)->ty2)); + CError_ASSERT(1657, IS_TYPE_CLASS(TYPE_MEMBER_POINTER(newnode->rtype)->ty2)); if (CClass_IsBaseClass(TYPE_CLASS(TYPE_MEMBER_POINTER(type)->ty2), TYPE_CLASS(TYPE_MEMBER_POINTER(newnode->rtype)->ty2), &depth, 0, 0)) { assign_value = 1000 - depth; @@ -1270,8 +1255,7 @@ ENode *CExpr_ClassPointerCast(BClassList *cls, ENode *origexpr, Boolean nullchec expr = origexpr; tclass = TYPE_CLASS(cls->type); do_nullcheck = 0; -#line 1691 - CError_ASSERT(cls); + CError_ASSERT(1691, cls); if (!IS_TYPE_POINTER_ONLY(origexpr->rtype)) { CError_Error(CErrorStr141); @@ -1346,10 +1330,8 @@ ENode *CExpr_GetClassAccessNode(BClassList *a, BClassList *b, ENode *expr, Objec expr->rtype = TYPE(cscope_currentclass); } -#line 1786 - CError_ASSERT(a); -#line 1787 - CError_ASSERT(IS_TYPE_CLASS(expr->rtype)); + CError_ASSERT(1786, a); + CError_ASSERT(1787, IS_TYPE_CLASS(expr->rtype)); tclass = TYPE_CLASS(expr->rtype); a = CScope_GetClassAccessPath(a, tclass); @@ -1411,8 +1393,7 @@ static short std_assign_check_overload(NameSpaceObjectList *list, TemplArg *temp if (IS_TYPE_FUNC(obj->type) && (TYPE_FUNC(obj->type)->flags & FUNC_FLAGS_100000)) { if (!found_non_template_func && CTempl_CanDeduceFunc(obj, TYPE_FUNC(type), templargs)) { instance = CTempl_DeduceFunc(obj, TYPE_FUNC(type), templargs, NULL, 0); -#line 1861 - CError_ASSERT(instance); + CError_ASSERT(1861, instance); if (is_typesame(instance->object->type, type)) { if (used_obj && used_obj != instance->object) is_ambig = 1; @@ -1458,7 +1439,7 @@ static short std_assign_check_overload(NameSpaceObjectList *list, TemplArg *temp } } -ENode *CExpr_ConvertToBool(ENode *expr, Boolean flag) { +ENode *CExpr_ConvertToBool(ENode *expr, Boolean isExplicit) { if (IS_TYPE_MEMBERPOINTER(expr->rtype)) expr = CExpr_ConvertToCondition(expr); @@ -1485,7 +1466,7 @@ ENode *CExpr_ConvertToBool(ENode *expr, Boolean flag) { break; default: CError_Error( - flag ? CErrorStr247 : CErrorStr209, + isExplicit ? CErrorStr247 : CErrorStr209, expr->rtype, expr->flags & ENODE_FLAG_QUALS, &stbool, @@ -1841,8 +1822,7 @@ short user_assign_check(ENode *expr, Type *type, UInt32 qual, Boolean flag1, Boo UInt16 chk; Boolean is_const, is_volatile; -#line 2378 - CError_ASSERT(copts.old_argmatch); + CError_ASSERT(2378, copts.old_argmatch); memclrw(&stdmatch, sizeof(Match5)); r24 = 0; @@ -1872,8 +1852,7 @@ short user_assign_check(ENode *expr, Type *type, UInt32 qual, Boolean flag1, Boo } if ((result = std_assign_check(r14, type, 0, flag3))) { CExpr_CalcStdAssign(result, &match_98, r17->functype, r17->qual, type, qual, 1); -#line 2419 - CError_ASSERT(r17->args && IS_TYPE_POINTER_ONLY(r17->args->type)); + CError_ASSERT(2419, r17->args && IS_TYPE_POINTER_ONLY(r17->args->type)); chk = expr->flags; if (!(is_const = (r17->args->qual & Q_CONST)) && (chk & Q_CONST) != 0) continue; @@ -1976,8 +1955,7 @@ short user_assign_check(ENode *expr, Type *type, UInt32 qual, Boolean flag1, Boo if (flag1) { if (r24) { r13 = TYPE_METHOD(r26->type); -#line 2537 - CError_ASSERT(r13->flags & FUNC_FLAGS_METHOD); + CError_ASSERT(2537, r13->flags & FUNC_FLAGS_METHOD); r15b = create_objectrefnode(r26); r26->flags |= OBJECT_FLAGS_UNUSED; r14d = lalloc(sizeof(ENodeList)); @@ -2092,8 +2070,7 @@ void CExpr_CheckArithmConversion(ENode *expr, Type *type) { if (IS_TYPE_INT(expr->rtype)) { if (IS_TYPE_FLOAT(type)) return; -#line 2772 - CError_ASSERT(IS_TYPE_INT(type)); + CError_ASSERT(2772, IS_TYPE_INT(type)); if (type->size > expr->rtype->size) return; @@ -2152,8 +2129,7 @@ ENode *get_address_of_temp_copy(ENode *expr, Boolean flag) { innertype = TYPE(&stunsignedlong); break; default: -#line 2857 - CError_FATAL(); + CError_FATAL(2857); } CMach_InitIntMem(innertype, expr->data.intval, buf); } else { @@ -2440,8 +2416,7 @@ ENode *CExpr_GetDefaultArgument(ENode *funcexpr, FuncArg *arg) { ENode *tmp; if (CTemplTool_IsTemplateArgumentDependentExpression(arg->dexpr)) { -#line 3264 - CError_ASSERT(ENODE_IS(funcexpr, EOBJREF)); + CError_ASSERT(3264, ENODE_IS(funcexpr, EOBJREF)); tmp = CTemplTool_DeduceDefaultArg( funcexpr->data.objref, CInline_CopyExpression(arg->dexpr, CopyMode0) @@ -2650,8 +2625,7 @@ ENode *CExpr_GenericFuncCall(BClassList *path, ENode *funcexpr, Boolean flag1, O scan_arg = tfunc->args; scan_expr = nodes; if (tfunc->flags & FUNC_FLAGS_METHOD) { -#line 3599 - CError_ASSERT(TYPE_METHOD(tfunc)->theclass->sominfo == NULL); + CError_ASSERT(3599, TYPE_METHOD(tfunc)->theclass->sominfo == NULL); } } @@ -2883,8 +2857,7 @@ static Boolean accept_conversion_type(Type *type, short mode) { case 3: return IS_TYPE_POINTER_ONLY(type); default: -#line 3912 - CError_FATAL(); + CError_FATAL(3912); return 0; } } @@ -3077,8 +3050,7 @@ static Boolean is_legal_type_combination(Type *left, Type *right, short mode) { diadic_arg2.type = right; return 1; default: -#line 4132 - CError_FATAL(); + CError_FATAL(4132); return 0; } } @@ -3272,8 +3244,7 @@ Boolean CExpr_CheckOperator(short token, ENode *left, ENode *right, Conversion * tk = lex(); return 1; } else { -#line 4371 - CError_FATAL(); + CError_FATAL(4371); } } return 0; @@ -3320,8 +3291,7 @@ Boolean CExpr_CheckOperator(short token, ENode *left, ENode *right, Conversion * tk = lex(); return 1; } else { -#line 4439 - CError_FATAL(); + CError_FATAL(4439); } } return 0; @@ -3344,8 +3314,7 @@ Boolean CExpr_CheckOperator(short token, ENode *left, ENode *right, Conversion * mylist_B0.object = pr2.obj_10; pr2.nsol_14 = &mylist_B0; } else { -#line 4470 - CError_ASSERT(pr2.nsol_14); + CError_ASSERT(4470, pr2.nsol_14); } if (token != '=' || (pr2.bcl_18->type == left->rtype && pr2.bcl_18->next == NULL)) { @@ -3406,15 +3375,13 @@ ENode *CExpr_ConstructObject(TypeClass *tclass, ENode *addr_expr, ENodeList *arg NameSpaceObjectList *ctorlist; BClassList path; -#line 4595 - CError_ASSERT(IS_TYPE_POINTER_ONLY(addr_expr->rtype)); + CError_ASSERT(4595, IS_TYPE_POINTER_ONLY(addr_expr->rtype)); addr_expr = makemonadicnode(addr_expr, EINDIRECT); addr_expr->rtype = TYPE(tclass); if (!flag3 && args && !args->next && args->node->rtype == TYPE(tclass) && !CClass_CopyConstructor(tclass)) { -#line 4605 - CError_ASSERT(IS_TYPE_CLASS(addr_expr->rtype)); + CError_ASSERT(4605, IS_TYPE_CLASS(addr_expr->rtype)); expr = makediadicnode(addr_expr, args->node, EASS); if (!flag1) expr = getnodeaddress(expr, 0); @@ -3502,8 +3469,7 @@ static ENode *CExpr_CopyPlacementNewArg(ENodeList *list) { switch (list->node->rtype->type) { default: -#line 4726 - CError_FATAL(); + CError_FATAL(4726); case TYPEINT: case TYPEFLOAT: case TYPEENUM: @@ -3523,12 +3489,10 @@ static ENode *CExpr_PlacementDeleteCall(Type *type, ENode *expr, Object *obj, Bo ENodeList *inputarg; Boolean outflag; -#line 4752 - CError_ASSERT(ENODE_IS(expr, EFUNCCALL) && ENODE_IS(expr->data.funccall.funcref, EOBJREF)); + CError_ASSERT(4752, ENODE_IS(expr, EFUNCCALL) && ENODE_IS(expr->data.funccall.funcref, EOBJREF)); funcobj = expr->data.funccall.funcref->data.objref; -#line 4756 - CError_ASSERT(IS_TYPE_FUNC(funcobj->type) && TYPE_FUNC(funcobj->type)->args && TYPE_FUNC(funcobj->type)->args->next); + CError_ASSERT(4756, IS_TYPE_FUNC(funcobj->type) && TYPE_FUNC(funcobj->type)->args && TYPE_FUNC(funcobj->type)->args->next); funcobj = CParser_FindDeallocationObject(type, TYPE_FUNC(funcobj->type)->args->next, flag1, flag2, &outflag); if (!funcobj) @@ -3546,8 +3510,7 @@ static ENode *CExpr_PlacementDeleteCall(Type *type, ENode *expr, Object *obj, Bo list->node = create_objectnode(obj); result->data.funccall.args = list; -#line 4780 - CError_ASSERT((inputarg = expr->data.funccall.args) && (inputarg = inputarg->next)); + CError_ASSERT(4780, (inputarg = expr->data.funccall.args) && (inputarg = inputarg->next)); do { list->next = lalloc(sizeof(ENodeList)); @@ -3688,12 +3651,10 @@ static ENode *CExpr_NewAlloc(Type *type, ENodeList *args, Boolean flag1, Boolean if (CScope_FindClassMemberObject(TYPE_CLASS(type), &pr, name)) { list = pr.nsol_14; obj = OBJECT(pr.obj_10); -#line 4935 - CError_ASSERT(list || obj); + CError_ASSERT(4935, list || obj); found = 1; } else if (TYPE_CLASS(type)->flags & CLASS_FLAGS_1) { -#line 4942 - CError_ASSERT(!flag2); + CError_ASSERT(4942, !flag2); obj = newh_func; found = 1; } @@ -3764,8 +3725,7 @@ static ENode *CExpr_NewExceptionSafeInit(ENode *expr, ENode *tryexpr) { expr->data.itc.tryexpr = tryexpr; break; default: -#line 5056 - CError_FATAL(); + CError_FATAL(5056); } return expr; } @@ -3834,7 +3794,7 @@ static ENode *CExpr_NewArray(Type *type, UInt32 qual, ENodeList *nodelist, Boole dtor = CClass_Destructor(TYPE_CLASS(innertype)); if (dtor) - dtor = CABI_GetDestructorObject(dtor, 1); + dtor = CABI_GetDestructorObject(dtor, CABIDestroy1); ass = NULL; if (firstarrayexpr) { @@ -4223,8 +4183,7 @@ ENode *scandelete(Boolean flag) { if (!flag) { result_expr = CABI_DestroyObject(dtor, expr, 2, 0, 1); } else { -#line 5650 - CError_ASSERT(!outflag); + CError_ASSERT(5650, !outflag); result_expr = CABI_DestroyObject(dtor, expr, 2, 0, 0); result_expr->rtype = TYPE(&void_ptr); result_expr = funccallexpr(obj, result_expr, NULL, NULL, NULL); diff --git a/compiler_and_linker/unsorted/CExprConvMatch.c b/compiler_and_linker/unsorted/CExprConvMatch.c index 9722dcb..7fdce02 100644 --- a/compiler_and_linker/unsorted/CExprConvMatch.c +++ b/compiler_and_linker/unsorted/CExprConvMatch.c @@ -1 +1,2518 @@ #include "compiler/CExpr.h" +#include "compiler/CABI.h" +#include "compiler/CClass.h" +#include "compiler/CDecl.h" +#include "compiler/CError.h" +#include "compiler/CInt64.h" +#include "compiler/CFunc.h" +#include "compiler/CMachine.h" +#include "compiler/CMangler.h" +#include "compiler/CObjC.h" +#include "compiler/CParser.h" +#include "compiler/CScope.h" +#include "compiler/CTemplateFunc.h" +#include "compiler/CodeGen.h" +#include "compiler/CompilerTools.h" +#include "compiler/objects.h" +#include "compiler/scopes.h" +#include "compiler/templates.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +typedef struct StandardConv { + Type *type1; + Type *type2; + UInt32 qual1; + UInt32 qual2; + Boolean x10; // unknown + Boolean x11; + Boolean x12; + Boolean x13; + Boolean x14; + Boolean x15; +} StandardConv; + +typedef enum EImplicitConvType { + ICT_0, + ICT_1, + ICT_2, + ICT_3 +} EImplicitConvType; + +typedef struct ImplicitConv { + EImplicitConvType type; + union { + struct { + Object *x2; + StandardConv standardConv; + } ic2; + struct { + StandardConv standardConv; + } ic3; + } u; +} ImplicitConv; + +typedef struct ConversionTypeList { + struct ConversionTypeList *next; + Object *func; + Type *type; + UInt32 qual; +} ConversionTypeList; + +typedef struct Match { + struct Match *next; + Object *object; + Object *specialfunc; + Type *type; + UInt32 qual; + Type *type2; + UInt32 qual2; + ImplicitConv conv[3]; +} Match; +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +// forward decls +static ENode *CExpr_DerivedToBase(ENode *expr, Type *type2, UInt32 qual2, Boolean flag1, Boolean flag2, Boolean flag3); + +static Type *CExpr_GetImplictObjectParamType(Object *object, UInt32 *qual) { + Type *type; + + CError_ASSERT(98, IS_TYPE_FUNC(object->type)); + CError_ASSERT(99, TYPE_FUNC(object->type)->flags & FUNC_FLAGS_METHOD); + CError_ASSERT(100, !TYPE_METHOD(object->type)->x26); + CError_ASSERT(101, TYPE_METHOD(object->type)->args); + + type = CDecl_NewRefPointerType(TYPE(TYPE_METHOD(object->type)->theclass)); + *qual = TYPE_METHOD(object->type)->args->qual & Q_CV; + return type; +} + +static Type *CExpr_GetParamType(Object *object, int index, UInt32 *qual) { + FuncArg *arg; + + CError_ASSERT(120, IS_TYPE_FUNC(object->type)); + CError_ASSERT(121, arg = TYPE_FUNC(object->type)->args); + if (IS_TYPEFUNC_NONSTATIC_METHOD(TYPE_FUNC(object->type))) + CError_ASSERT(125, arg = arg->next); + + while (index > 0) { + CError_ASSERT(129, arg = arg->next); + index--; + } + + *qual = arg->qual & Q_CV; + return arg->type; +} + +static Boolean CExpr_HasNParams(Object *object, int count) { + FuncArg *arg; + int i; + + CError_ASSERT(146, IS_TYPE_FUNC(object->type)); + CError_ASSERT(147, arg = TYPE_FUNC(object->type)->args); + if (IS_TYPEFUNC_NONSTATIC_METHOD(TYPE_FUNC(object->type))) + arg = arg->next; + + i = 0; + while (arg) { + arg = arg->next; + i++; + } + + return i == count; +} + +typedef enum TypeCompareMode { + TCM_0, + TCM_1, + TCM_2 +} TypeCompareMode; + +static Boolean CExpr_TypeCompare(Type *typeA, UInt32 qualA, Type *typeB, UInt32 qualB, TypeCompareMode mode) { + if (typeA->type != typeB->type) + return 0; + + switch (mode) { + case TCM_0: + while (1) { + switch (typeA->type) { + case TYPEPOINTER: + typeA = TPTR_TARGET(typeA); + typeB = TPTR_TARGET(typeB); + if (typeA->type != typeB->type) + return 0; + continue; + + case TYPEMEMBERPOINTER: + if (!is_typesame(TYPE_MEMBER_POINTER(typeA)->ty2, TYPE_MEMBER_POINTER(typeB)->ty2)) + return 0; + typeA = TYPE_MEMBER_POINTER(typeA)->ty1; + typeB = TYPE_MEMBER_POINTER(typeB)->ty1; + if (typeA->type != typeB->type) + return 0; + continue; + } + break; + } + break; + + case TCM_1: + switch (typeA->type) { + case TYPEPOINTER: + if ((qualA & Q_CV) != (qualB & Q_CV)) + return 0; + + typeA = TPTR_TARGET(typeA); + typeB = TPTR_TARGET(typeB); + break; + + case TYPEMEMBERPOINTER: + if ((qualA & Q_CV) != (qualB & Q_CV)) + return 0; + + if (!is_typesame(TYPE_MEMBER_POINTER(typeA)->ty2, TYPE_MEMBER_POINTER(typeB)->ty2)) + return 0; + typeA = TYPE_MEMBER_POINTER(typeA)->ty1; + typeB = TYPE_MEMBER_POINTER(typeB)->ty1; + break; + } + break; + + case TCM_2: + if ((qualA & Q_CV) != (qualB & Q_CV)) + return 0; + break; + } + + return is_typesame(typeA, typeB); +} + +static int CExpr_IsReferenceCompatible(Type *typeA, UInt32 qualA, Type *typeB, UInt32 qualB) { + if (CParser_IsSameOrMoreCVQualified(CParser_GetCVTypeQualifiers(typeA, qualA), CParser_GetCVTypeQualifiers(typeB, qualB))) { + if (CExpr_TypeCompare(typeA, qualA, typeB, qualB, TCM_1)) + return 1; + + if (IS_TYPE_CLASS(typeB) && IS_TYPE_CLASS(typeA)) { + short depth; + Boolean isambigbase; + if (CClass_GetBasePath(TYPE_CLASS(typeB), TYPE_CLASS(typeA), &depth, &isambigbase)) + return 2; + } + } + + return 0; +} + +static Boolean CExpr_IsBaseOf(TypeClass *baseclass, TypeClass *superclass) { + ClassList *base; + + for (base = superclass->bases; base; base = base->next) { + if (base->base == baseclass || CExpr_IsBaseOf(baseclass, base->base)) + return 1; + } + + return 0; +} + +static Boolean CExpr_IsBetterClassConversion(TypeClass *a, TypeClass *b, TypeClass *c, TypeClass *d) { + if (a == c) + return CExpr_IsBaseOf(d, b); + if (b == d) + return CExpr_IsBaseOf(a, c); + return 0; +} + +inline Boolean Inline_501D40(Type *a, Type *b) { + return (a == TYPE(&stbool)) && (IS_TYPE_POINTER_ONLY(b) || IS_TYPE_MEMBERPOINTER(b)); +} + +static Boolean CExpr_IsBetterStandardConv(StandardConv *a, StandardConv *b) { + Boolean flag10; + Boolean flag3; + + flag10 = 1; + flag3 = 0; + + if (b->x11) { + if (!a->x11) + flag3 = 1; + } else { + if (a->x11) + flag10 = 0; + } + + if (b->x12) { + if (!a->x12) + flag3 = 1; + } else { + if (a->x12) + flag10 = 0; + } + + if (b->x13) { + if (a->x13) { + if (Inline_501D40(b->type2, b->type1)) { + if (!Inline_501D40(a->type2, a->type1)) + return 1; + } else { + if (Inline_501D40(a->type2, a->type1)) + return 0; + } + } else { + flag3 = 1; + } + } else { + if (a->x13) + flag10 = 0; + } + + if (flag10 && flag3) + return 1; + + if (!a->x13) { + if (b->x13) + return 1; + + if (a->x12) { + if (!b->x12) + return 0; + } else { + if (b->x12) + return 1; + } + } else { + if (!b->x13) + return 0; + } + + if ( + IS_TYPE_POINTER_ONLY(a->type1) && + IS_TYPE_CLASS(TPTR_TARGET(a->type1)) && + IS_TYPE_POINTER_ONLY(a->type2) && + IS_TYPE_POINTER_ONLY(b->type1) && + IS_TYPE_CLASS(TPTR_TARGET(b->type1)) && + IS_TYPE_POINTER_ONLY(b->type2) + ) + { + if (TPTR_TARGET(b->type2) == &stvoid) { + if (TPTR_TARGET(a->type2) == &stvoid) { + if (CExpr_IsBaseOf(TYPE_CLASS(TPTR_TARGET(a->type1)), TYPE_CLASS(TPTR_TARGET(b->type1)))) + return 1; + } else { + if (TPTR_TARGET(a->type1) == TPTR_TARGET(b->type1) && IS_TYPE_CLASS(TPTR_TARGET(a->type2))) + return 1; + } + } else if (IS_TYPE_CLASS(TPTR_TARGET(a->type2)) && IS_TYPE_CLASS(TPTR_TARGET(b->type2))) { + if (CExpr_IsBetterClassConversion( + TYPE_CLASS(TPTR_TARGET(a->type1)), + TYPE_CLASS(TPTR_TARGET(a->type2)), + TYPE_CLASS(TPTR_TARGET(b->type1)), + TYPE_CLASS(TPTR_TARGET(b->type2)) + )) + return 1; + } + } + + if ( + IS_TYPE_CLASS(a->type1) && + IS_TYPE_CLASS(a->type2) && + IS_TYPE_CLASS(b->type1) && + IS_TYPE_CLASS(b->type2) && + CExpr_IsBetterClassConversion( + TYPE_CLASS(a->type1), + TYPE_CLASS(a->type2), + TYPE_CLASS(b->type1), + TYPE_CLASS(b->type2) + ) + ) + return 1; + + if ( + IS_TYPE_MEMBERPOINTER(a->type1) && + IS_TYPE_MEMBERPOINTER(a->type2) && + IS_TYPE_MEMBERPOINTER(b->type1) && + IS_TYPE_MEMBERPOINTER(b->type2) && + IS_TYPE_CLASS(TYPE_MEMBER_POINTER(a->type1)->ty2) && + IS_TYPE_CLASS(TYPE_MEMBER_POINTER(a->type2)->ty2) && + IS_TYPE_CLASS(TYPE_MEMBER_POINTER(b->type1)->ty2) && + IS_TYPE_CLASS(TYPE_MEMBER_POINTER(b->type2)->ty2) && + CExpr_IsBetterClassConversion( + TYPE_CLASS(TYPE_MEMBER_POINTER(b->type1)->ty2), + TYPE_CLASS(TYPE_MEMBER_POINTER(b->type2)->ty2), + TYPE_CLASS(TYPE_MEMBER_POINTER(a->type1)->ty2), + TYPE_CLASS(TYPE_MEMBER_POINTER(a->type2)->ty2) + ) + ) + return 1; + + if ( + a->x14 && + b->x14 && + CExpr_TypeCompare(a->type2, a->qual2, b->type2, b->qual2, TCM_1) && + CParser_IsMoreCVQualified( + CParser_GetTypeQualifiers(b->type2, b->qual2), + CParser_GetTypeQualifiers(a->type2, a->qual2) + ) + ) + return 1; + + return 0; +} + +static Boolean CExpr_IsBetterImplicitConv(ImplicitConv *a, ImplicitConv *b) { + if (a->type > b->type) + return 1; + if (a->type != b->type) + return 0; + + if (a->type == ICT_3) + return CExpr_IsBetterStandardConv(&a->u.ic3.standardConv, &b->u.ic3.standardConv); + + if (a->type == ICT_2 && a->u.ic2.x2 == b->u.ic2.x2 && CExpr_IsBetterStandardConv(&a->u.ic2.standardConv, &b->u.ic2.standardConv)) + return 1; + + return 0; +} + +typedef enum SSCRMode { + SSCR_0, + SSCR_1, + SSCR_2 +} SSCRMode; + +static Boolean CExpr_SetupStandardConversionResult(ENode *expr, Type *type2, UInt32 qual2, SSCRMode mode, Boolean x14, Boolean refFlag, StandardConv *result) { + UInt32 cv1; + UInt32 cv2; + + if (x14) { + if (!CParser_IsConst(type2, qual2)) { + if (!refFlag && !CExpr_IsLValue(expr)) + return 0; + if (mode != SSCR_0 && !IS_TYPE_CLASS(type2)) + return 0; + } + + cv2 = CParser_GetTypeQualifiers(type2, qual2) & Q_CV; + cv1 = CParser_GetTypeQualifiers(expr->rtype, ENODE_QUALS(expr)) & Q_CV; + if (cv2 != cv1 && !CParser_IsMoreCVQualified(cv2, cv1)) + return 0; + } + + memclrw(result, sizeof(StandardConv)); + result->type2 = type2; + result->qual2 = qual2; + result->type1 = expr->rtype; + result->qual1 = ENODE_QUALS(expr); + result->x14 = x14; + + switch (mode) { + case SSCR_0: + break; + case SSCR_1: + result->x12 = 1; + break; + case SSCR_2: + result->x13 = 1; + break; + default: + CError_FATAL(581); + } + + return 1; +} + +typedef enum MysteryEnum { + ME_0, + ME_1, + ME_255 = 255 +} MysteryEnum; + +inline MysteryEnum Inline_501FF0(UInt32 qual1, UInt32 qual2) { + if ((qual1 & Q_CV) == (qual2 & Q_CV)) + return ME_0; + + if (((qual2 & Q_CONST) && !(qual1 & Q_CONST)) || ((qual2 & Q_VOLATILE) && !(qual1 & Q_VOLATILE))) + return ME_255; + + return ME_1; +} + +static Boolean CExpr_SetQualConversionResult(Type *type1, UInt32 qual1, Type *type2, UInt32 qual2, StandardConv *result) { + Boolean flag = 1; + UInt32 cv1; + UInt32 cv2; + + while (1) { + cv1 = CParser_GetCVTypeQualifiers(type1, qual1); + cv2 = CParser_GetCVTypeQualifiers(type2, qual2); + + switch (Inline_501FF0(cv1, cv2)) { + case ME_0: + break; + + case ME_1: + result->x11 = 1; + if (!flag) + return 0; + break; + + default: + return 0; + } + + if (!(cv1 & Q_CONST)) + flag = 0; + + if (IS_TYPE_POINTER_ONLY(type1)) { + CError_ASSERT(635, IS_TYPE_POINTER_ONLY(type2)); + type1 = TPTR_TARGET(type1); + type2 = TPTR_TARGET(type2); + } else { + if (!IS_TYPE_MEMBERPOINTER(type1)) + return 1; + + CError_ASSERT(642, IS_TYPE_MEMBERPOINTER(type2)); + type1 = TYPE_MEMBER_POINTER(type1)->ty1; + type2 = TYPE_MEMBER_POINTER(type2)->ty1; + } + } +} + +static Boolean CExpr_OverloadFuncMatch(NameSpaceObjectList *list, TemplArg *templargs, Type *type, ENode **outExpr) { + Object *object; + TemplFuncInstance *inst; + ENode *expr; + FuncArg *arg; + int i; + ObjectList *objlist; + Object *object26; + ObjectList *objlist25; + ObjectList *objlist24; + Boolean flag23; + + if (!IS_TYPE_POINTER_ONLY(type) || !IS_TYPE_FUNC(type = TPTR_TARGET(type))) + return 0; + + object26 = NULL; + objlist25 = NULL; + objlist24 = NULL; + flag23 = 0; + + while (list) { + object = OBJECT(list->object); + if (object->otype == OT_OBJECT) { + if (IS_TEMPL_FUNC(object->type)) { + if (!flag23 && CTempl_CanDeduceFunc(object, TYPE_FUNC(type), templargs)) { + CError_ASSERT(685, inst = CTempl_DeduceFunc(object, TYPE_FUNC(type), templargs, NULL, 0)); + if (is_typesame(inst->object->type, type)) { + objlist = lalloc(sizeof(ObjectList)); + objlist->next = objlist24; + objlist->object = object; + objlist24 = objlist; + + if (object26 && object26 != inst->object) { + objlist = lalloc(sizeof(ObjectList)); + objlist->next = objlist25; + objlist->object = inst->object; + objlist25 = objlist; + } else { + object26 = inst->object; + } + } + } + } else if (is_typesame(object->type, type)) { + if (object26 && flag23) { + Object *checkA, *checkB; + checkA = object; + if (checkA->datatype == DALIAS) + checkA = checkA->u.alias.object; + checkB = object26; + if (checkB->datatype == DALIAS) + checkB = checkB->u.alias.object; + if (checkA != checkB) { + objlist = lalloc(sizeof(ObjectList)); + objlist->next = objlist25; + objlist->object = object; + objlist25 = objlist; + } + } else { + objlist25 = NULL; + object26 = object; + } + flag23 = 1; + } + } + list = list->next; + } + + if (object26) { + if (outExpr) { + if (objlist25) { + i = 0; + for (arg = TYPE_FUNC(object->type)->args; arg; arg = arg->next) + i++; + + if (!flag23 && (object = CTempl_PartialOrdering(objlist24->object, objlist24->next, i))) { + CError_ASSERT(741, inst = CTempl_DeduceFunc(object, TYPE_FUNC(type), templargs, NULL, 0)); + object26 = inst->object; + } else { + CError_OverloadedFunctionError(object26, objlist25); + } + } + + expr = CExpr_MakeObjRefNode(object26, 1); + *outExpr = expr; + expr->rtype = CDecl_NewPointerType(object26->type); + expr->flags = object->qual & ENODE_FLAG_QUALS; + object26->flags |= OBJECT_FLAGS_UNUSED; + if (object26->datatype == DINLINEFUNC) + CError_Error(CErrorStr175); + } + + return 1; + } + + return 0; +} + +static Boolean CExpr_StandardConversionMatch(ENode *expr, Type *type2, UInt32 qual2, Boolean x14, StandardConv *result) { + Type *type1; + UInt32 qual1; + Boolean refFlag; + Type *inner2; + Type *inner1; + SSCRMode mode; + NameSpaceObjectList list; + + if (IS_TYPE_REFERENCE(type2)) { + type2 = TPTR_TARGET(type2); + if (IS_TYPE_POINTER_ONLY(type2)) + expr = pointer_generation(expr); + refFlag = 1; + } else { + if ( + (IS_TYPE_ARRAY(expr->rtype) && !IS_TYPE_ARRAY(type2)) || + (IS_TYPE_FUNC(expr->rtype) && !IS_TYPE_FUNC(type2)) + ) + expr = pointer_generation(expr); + refFlag = 0; + } + + type1 = expr->rtype; + qual1 = ENODE_QUALS(expr); + + if (IS_TYPE_POINTER_ONLY(type2)) { + if (ENODE_IS(expr, EINTCONST) && CInt64_IsZero(&expr->data.intval)) { + if (IS_TYPE_INT(type1) || (!copts.cplusplus && IS_TYPE_ENUM(type1))) + return CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, x14, refFlag, result); + } + + if ( + IS_TYPE_INT(expr->rtype) && + ENODE_IS_INDIRECT_TO(expr, EOBJREF) && + (expr->data.monadic->data.objref->qual & Q_10000) && + CInt64_IsZero(&expr->data.monadic->data.objref->u.data.u.intconst) + ) + return CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, x14, refFlag, result); + + if (ENODE_IS(expr, EOBJLIST)) + return CExpr_OverloadFuncMatch(expr->data.objlist.list, expr->data.objlist.templargs, type2, NULL) && + CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_0, refFlag, x14, result); + + if (ENODE_IS(expr, EOBJREF) && IS_TEMPL_FUNC(expr->data.objref->type)) { + list.next = NULL; + list.object = OBJ_BASE(expr->data.objref); + return CExpr_OverloadFuncMatch(&list, NULL, type2, NULL) && + CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_0, refFlag, x14, result); + } + + if (IS_TYPE_POINTER_ONLY(type1)) { + if ( + ENODE_IS(expr, ESTRINGCONST) && + TPTR_TARGET(type2) == TPTR_TARGET(type1) && + !(qual2 & Q_CONST) && + ( + TPTR_TARGET(type2) == TYPE(&stchar) || + TPTR_TARGET(type2) == TYPE(&stunsignedchar) || + TPTR_TARGET(type2) == CParser_GetWCharType() + ) + ) + { + if ( + CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_0, refFlag, x14, result) && + CExpr_SetQualConversionResult(TPTR_TARGET(type2), qual2, TPTR_TARGET(type1), qual1 & ~Q_CONST, result) + ) + { + result->x11 = 1; + return 1; + } else { + return 0; + } + } + + if (copts.objective_c && CObjC_IsCompatibleType(expr->rtype, type2)) + return CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, x14, refFlag, result); + + if (IS_TYPE_VOID(TPTR_TARGET(type2)) || (!copts.cplusplus && IS_TYPE_VOID(TPTR_TARGET(type1)))) { + if (CExpr_SetupStandardConversionResult(expr, type2, qual2, IS_TYPE_VOID(TPTR_TARGET(type1)) ? SSCR_0 : SSCR_2, refFlag, x14, result)) { + switch (Inline_501FF0(qual2, CParser_GetCVTypeQualifiers(TPTR_TARGET(type1), qual1))) { + case ME_1: + result->x11 = 1; + case ME_0: + return 1; + default: + return 0; + } + } else { + return 0; + } + } + + inner2 = TPTR_TARGET(type2); + inner1 = TPTR_TARGET(type1); + while (1) { + if (inner2->type != inner1->type) + break; + + switch (inner2->type) { + case TYPEPOINTER: + inner2 = TPTR_TARGET(inner2); + inner1 = TPTR_TARGET(inner1); + continue; + case TYPEMEMBERPOINTER: + if (!is_typesame(TYPE_MEMBER_POINTER(inner2)->ty2, TYPE_MEMBER_POINTER(inner1)->ty2)) + break; + + inner2 = TYPE_MEMBER_POINTER(inner2)->ty1; + inner1 = TYPE_MEMBER_POINTER(inner1)->ty1; + if (!IS_TYPE_POINTER_ONLY(inner2) && !IS_TYPE_MEMBERPOINTER(inner2)) { + if (!is_memberpointerequal(inner2, inner1)) + break; + + if (CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_0, refFlag, x14, result)) + return CExpr_SetQualConversionResult(TPTR_TARGET(type2), qual2, TPTR_TARGET(type1), qual1, result); + else + return 0; + } + continue; + default: + if (!is_typesame(inner2, inner1)) + break; + + if (CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_0, refFlag, x14, result)) + return CExpr_SetQualConversionResult(TPTR_TARGET(type2), qual2, TPTR_TARGET(type1), qual1, result); + else + return 0; + } + + break; + } + + if (IS_TYPE_CLASS(TPTR_TARGET(type2)) && IS_TYPE_CLASS(TPTR_TARGET(type1))) { + short depth; + Boolean isambigbase; + if (CClass_GetBasePath(TYPE_CLASS(TPTR_TARGET(type1)), TYPE_CLASS(TPTR_TARGET(type2)), &depth, &isambigbase)) { + if (CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, refFlag, x14, result)) + return CExpr_SetQualConversionResult(TPTR_TARGET(type2), qual2, TPTR_TARGET(type1), qual1, result); + else + return 0; + } + } + } + + if (copts.mpwc_relax && !copts.cplusplus && IS_TYPE_POINTER_ONLY(type1)) { + if (CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, refFlag, x14, result)) + return 1; + } + + return 0; + } + + if (is_typesame(type2, type1)) + return CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_0, refFlag, x14, result); + + if (type2 == TYPE(&stbool)) { + switch (type1->type) { + case TYPEINT: + case TYPEFLOAT: + case TYPEENUM: + case TYPEMEMBERPOINTER: + case TYPEPOINTER: + return CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, refFlag, x14, result); + default: + return 0; + } + } + + if (IS_TYPE_MEMBERPOINTER(type2)) { + if (ENODE_IS(expr, EINTCONST) && CInt64_IsZero(&expr->data.intval)) { + if (IS_TYPE_INT(type1) || (!copts.cplusplus && IS_TYPE_ENUM(type1))) + return CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, refFlag, x14, result); + } + + if (ENODE_IS(expr, EMEMBER)) { + expr = getpointertomemberfunc(expr, type2, 0); + type1 = expr->rtype; + } + + if (IS_TYPE_MEMBERPOINTER(type1)) { + short depth; + Boolean isambigbase; + + CError_ASSERT(996, IS_TYPE_CLASS(TYPE_MEMBER_POINTER(type2)->ty2) && IS_TYPE_CLASS(TYPE_MEMBER_POINTER(type1)->ty2)); + if (!is_memberpointerequal(TYPE_MEMBER_POINTER(type2)->ty1, TYPE_MEMBER_POINTER(type1)->ty1)) + return 0; + + if ( + TYPE_MEMBER_POINTER(type2)->ty2 == TYPE_MEMBER_POINTER(type1)->ty2 || + CClass_GetBasePath(TYPE_CLASS(TYPE_MEMBER_POINTER(type2)->ty2), TYPE_CLASS(TYPE_MEMBER_POINTER(type1)->ty2), &depth, &isambigbase) + ) + { + if (CExpr_SetupStandardConversionResult(expr, type2, qual2, SSCR_2, refFlag, x14, result)) + return CExpr_SetQualConversionResult(TYPE_MEMBER_POINTER(type2)->ty1, qual2, TYPE_MEMBER_POINTER(type1)->ty1, qual1, result); + else + return 0; + } + } + + return 0; + } + + mode = SSCR_2; + switch (type1->type) { + case TYPEINT: + switch (type2->type) { + case TYPEINT: + if (TYPE_INTEGRAL(type1)->integral < IT_INT) { + if (type2 == TYPE(&stsignedint)) { + if (type1->size < type2->size || !is_unsigned(type1)) + mode = SSCR_1; + } else if (type2 == TYPE(&stunsignedint)) { + if (type2->size == type1->size && is_unsigned(type1)) + mode = SSCR_1; + } + } + break; + case TYPEFLOAT: + break; + case TYPEENUM: + if (copts.cplusplus) + return 0; + break; + default: + return 0; + } + break; + + case TYPEFLOAT: + switch (type2->type) { + case TYPEINT: + break; + case TYPEFLOAT: + if (type2 == TYPE(&stdouble)) { + if (type1 == TYPE(&stfloat) || type1 == TYPE(&stshortdouble)) + mode = SSCR_1; + } + break; + case TYPEENUM: + if (copts.cplusplus) + return 0; + break; + default: + return 0; + } + break; + + case TYPEENUM: + switch (type2->type) { + case TYPEINT: + if (TYPE_INTEGRAL(TYPE_ENUM(expr->rtype)->enumtype)->integral < IT_INT) { + if (type1->size == type2->size && is_unsigned(TYPE_ENUM(type1)->enumtype)) { + if (type2 == TYPE(&stunsignedint)) + mode = SSCR_1; + } else { + if (type2 == TYPE(&stsignedint)) + mode = SSCR_1; + } + } else { + if (TYPE_ENUM(type1)->enumtype == type2) + mode = SSCR_1; + } + break; + case TYPEFLOAT: + break; + case TYPEENUM: + if (copts.cplusplus) + return 0; + break; + default: + return 0; + } + break; + + case TYPECLASS: { + short depth; + Boolean isambigbase; + + if (!IS_TYPE_CLASS(type1) || !CClass_GetBasePath(TYPE_CLASS(type1), TYPE_CLASS(type2), &depth, &isambigbase)) + return 0; + break; + } + + default: + return 0; + } + + return CExpr_SetupStandardConversionResult(expr, type2, qual2, mode, refFlag, x14, result); +} + +static ENode *CExpr_UserConversion(ENode *expr, Type *type2, UInt32 qual2, ImplicitConv *result, Boolean flag1, Boolean isExplicit, Boolean flag3) { + Object *object28; + Object *object27; + Object *object26; + ObjectList *objlist25; + ObjectList *objlist24; + ObjectList *objlist; + TypeFunc *tfunc23; + Type *tmptype23; + NameSpaceObjectList *list22; + Boolean flag22; + Boolean flag21; + FuncArg *arg21; + Boolean flag20; + ENode *newExpr; + ENode *funcref; + ENode *tmpExpr; + ENodeList *arglist; + UInt32 q1; + UInt32 q2; + StandardConv sc3; + StandardConv sc2; + StandardConv sc1; + ConversionIterator convIter; + ENodeList myarglist; + ObjectList myobjlist; + BClassList path; + + object28 = NULL; + object27 = NULL; + objlist25 = NULL; + objlist24 = NULL; + + if (type2->size == 0) + CDecl_CompleteType(type2); + if (expr->rtype->size == 0) + CDecl_CompleteType(expr->rtype); + + if (IS_TYPE_CLASS(expr->rtype)) { + CExpr_ConversionIteratorInit(&convIter, TYPE_CLASS(expr->rtype)); + flag22 = 1; + while ((object26 = CExpr_ConversionIteratorNext(&convIter))) { + tfunc23 = TYPE_FUNC(object26->type); + if (tfunc23->flags & FUNC_FLAGS_100000) { + object26 = CTempl_DeduceFromConversion(object26, type2, qual2); + if (!object26) + continue; + tfunc23 = TYPE_FUNC(object26->type); + } + + if (flag3) { + if ( + !IS_TYPE_REFERENCE(tfunc23->functype) || + !CExpr_IsReferenceCompatible(type2, qual2, TPTR_TARGET(tfunc23->functype), tfunc23->qual) + ) + continue; + } + + CError_ASSERT(1230, tfunc23->args && IS_TYPE_POINTER_ONLY(tfunc23->args->type)); + + q1 = ENODE_QUALS(expr); + q2 = tfunc23->args->qual; + if ((q1 & Q_CV) != (q2 & Q_CV)) { + if (!flag22) + continue; + if ((q1 & Q_CONST) && !(q2 & Q_CONST)) + continue; + if ((q1 & Q_VOLATILE) && !(q2 & Q_VOLATILE)) + continue; + flag21 = 1; + } else { + flag21 = 0; + } + + newExpr = CExpr_NewENode(ETEMP); + newExpr->rtype = tfunc23->functype; + newExpr->flags = tfunc23->qual & ENODE_FLAG_QUALS; + flag20 = 0; + + if (IS_TYPE_REFERENCE(newExpr->rtype)) { + newExpr->rtype = TPTR_TARGET(newExpr->rtype); + if (!CParser_IsConst(newExpr->rtype, tfunc23->qual)) { + newExpr = makemonadicnode(newExpr, EINDIRECT); + newExpr->data.monadic->rtype = TYPE(&void_ptr); + newExpr = makemonadicnode(newExpr, EINDIRECT); + newExpr->data.monadic->rtype = TYPE(&void_ptr); + flag20 = 1; + } + } + + if (CExpr_StandardConversionMatch(newExpr, type2, qual2, 0, &sc1)) { + if (flag22 && !flag21) { + object28 = NULL; + objlist25 = NULL; + flag22 = 0; + } + + if (object28 && object28 != object26) { + if (CExpr_IsBetterStandardConv(&sc3, &sc1)) + continue; + + if (!CExpr_IsBetterStandardConv(&sc1, &sc3)) { + objlist = lalloc(sizeof(ObjectList)); + objlist->next = objlist25; + objlist->object = object28; + objlist25 = objlist; + } else { + objlist25 = NULL; + } + } + + object28 = object26; + sc3 = sc1; + sc3.x15 = flag20; + } + } + } + + if (!flag3 && IS_TYPE_CLASS(type2) && (list22 = CClass_Constructor(TYPE_CLASS(type2)))) { + for (; list22; list22 = list22->next) { + object26 = OBJECT(list22->object); + if ( + object26->otype == OT_OBJECT && + IS_TYPE_FUNC(tfunc23 = TYPE_FUNC(object26->type)) && + (isExplicit || !(object26->qual & Q_EXPLICIT)) + ) + { + if (tfunc23->flags & FUNC_FLAGS_100000) { + myarglist.next = NULL; + myarglist.node = expr; + object26 = CTempl_DeduceFromFunctionCall(object26, NULL, &myarglist); + if (!object26) + continue; + tfunc23 = TYPE_FUNC(object26->type); + } + + if (!(arg21 = tfunc23->args)) + continue; + if (!(arg21 = arg21->next)) + continue; + if ((TYPE_CLASS(type2)->flags & CLASS_FLAGS_20) && !(arg21 = arg21->next)) + continue; + if (arg21 == &elipsis) + continue; + if (arg21->next && !arg21->next->dexpr && arg21->next != &elipsis) + continue; + + tmptype23 = arg21->type; + if (IS_TYPE_REFERENCE(tmptype23)) { + tmptype23 = TPTR_TARGET(tmptype23); + if (!CParser_IsConst(tmptype23, arg21->qual) && !CExpr_IsLValue(expr)) + continue; + } + + if (CExpr_StandardConversionMatch(expr, tmptype23, arg21->qual, 0, &sc1)) { + if (object27) { + if (!object26->u.func.inst && !object27->u.func.inst) + continue; + if (CExpr_IsBetterStandardConv(&sc2, &sc1)) + continue; + + if (!CExpr_IsBetterStandardConv(&sc1, &sc2)) { + if (!object26->u.func.inst && object27->u.func.inst) { + objlist24 = NULL; + } else { + objlist = lalloc(sizeof(ObjectList)); + objlist->next = objlist25; + objlist->object = object28; + objlist25 = objlist; + } + } else { + objlist25 = NULL; + } + } + + object27 = object26; + sc2 = sc1; + } + } + } + } + + if (object28 && object27) { + if (!CExpr_IsBetterStandardConv(&sc2, &sc3)) { + if (!CExpr_IsBetterStandardConv(&sc3, &sc2)) { + if (result) { + result->type = ICT_2; + result->u.ic2.x2 = object28; + result->u.ic2.standardConv = sc3; + } + if (flag1) { + myobjlist.next = NULL; + myobjlist.object = object27; + CError_OverloadedFunctionError(object28, &myobjlist); + } + } else { + object27 = NULL; + } + } else { + object28 = NULL; + } + } + + if (object28) { + if (result) { + result->type = ICT_2; + result->u.ic2.x2 = object28; + result->u.ic2.standardConv = sc3; + } + if (!flag1) + return expr; + if (objlist25) + CError_OverloadedFunctionError(object28, objlist25); + tfunc23 = TYPE_FUNC(object28->type); + CError_ASSERT(1416, IS_TYPEFUNC_METHOD(tfunc23)); + + funcref = create_objectrefnode(object28); + object28->flags |= OBJECT_FLAGS_UNUSED; + + arglist = lalloc(sizeof(ENodeList)); + arglist->next = NULL; + + expr = getnodeaddress(expr, 0); + arglist->node = CExpr_AssignmentPromotion( + expr, + CDecl_NewPointerType(TYPE(TYPE_METHOD(tfunc23)->theclass)), + expr->flags, + 0); + + newExpr = lalloc(sizeof(ENode)); + newExpr->type = EFUNCCALL; + newExpr->cost = 4; + newExpr->rtype = tfunc23->functype; + newExpr->flags = tfunc23->qual & ENODE_FLAG_QUALS; + newExpr->data.funccall.funcref = funcref; + newExpr->data.funccall.args = arglist; + newExpr->data.funccall.functype = TYPE_FUNC(object28->type); + newExpr = CExpr_AdjustFunctionCall(newExpr); + newExpr = checkreference(newExpr); + + if (newExpr->rtype != type2) { + if (flag3) { + tmpExpr = CExpr_DerivedToBase(newExpr, type2, qual2, 1, 0, 1); + if (tmpExpr) + return tmpExpr; + } + newExpr = CExpr_Convert(newExpr, type2, qual2, 0, 1); + } + return newExpr; + } + + if (object27) { + if (result) { + result->type = ICT_2; + result->u.ic2.x2 = object27; + result->u.ic2.standardConv = sc2; + } + if (!flag1) + return expr; + if (objlist24) + CError_OverloadedFunctionError(object27, objlist24); + + arglist = lalloc(sizeof(ENodeList)); + arglist->next = NULL; + arglist->node = expr; + + if (TYPE_CLASS(type2)->flags & CLASS_FLAGS_20) { + arglist->next = lalloc(sizeof(ENodeList)); + arglist->next->node = expr; + arglist->next->next = NULL; + arglist->node = intconstnode(TYPE(&stsignedshort), 1); + } + + path.next = NULL; + path.type = type2; + + tmpExpr = makemonadicnode(create_temp_node(type2), EINDIRECT); + tmpExpr->rtype = type2; + + newExpr = CExpr_GenericFuncCall( + &path, tmpExpr, 0, object27, NULL, NULL, arglist, 0, 0, 1 + ); + + if (ENODE_IS2(newExpr, EFUNCCALL, EFUNCCALLP)) { + newExpr->rtype = CDecl_NewPointerType(type2); + newExpr = makemonadicnode(newExpr, EINDIRECT); + newExpr->rtype = type2; + } + + return newExpr; + } + + return NULL; +} + +static Boolean CExpr_UserConversionMatch(ENode *expr, Type *type2, UInt32 qual2, ImplicitConv *result) { + Boolean flag; + + if (IS_TYPE_REFERENCE(type2)) { + type2 = TPTR_TARGET(type2); + flag = !CParser_IsConst(type2, qual2); + } else { + expr = pointer_generation(expr); + flag = 0; + } + + if (CExpr_UserConversion(expr, type2, qual2, result, 0, 0, flag)) + return 1; + + return 0; +} + +static Boolean CExpr_ImplicitConversionMatch(ENode *expr, Type *type2, UInt32 qual2, ImplicitConv *result) { + if (CExpr_StandardConversionMatch(expr, type2, qual2, 0, &result->u.ic3.standardConv)) { + result->type = ICT_3; + return 1; + } + + if (IS_TYPE_CLASS(expr->rtype) || IS_TYPE_CLASS(type2) || (IS_TYPE_REFERENCE(type2) && IS_TYPE_CLASS(TPTR_TARGET(type2)))) { + if (CExpr_UserConversionMatch(expr, type2, qual2, result)) { + result->type = ICT_2; + return 1; + } + } + + return 0; +} + +Boolean CExpr_CanImplicitlyConvert(ENode *expr, Type *type2, UInt32 qual2) { + ImplicitConv result; + return CExpr_ImplicitConversionMatch(expr, type2, qual2, &result); +} + +static ENode *CExpr_DerivedToBase(ENode *expr, Type *type2, UInt32 qual2, Boolean flag1, Boolean nullcheckflag, Boolean pathcheckflag) { + BClassList *path; + short depth; + Boolean isambigbase; + + if ( + IS_TYPE_CLASS(type2) && + IS_TYPE_CLASS(expr->rtype) && + (path = CClass_GetBasePath(TYPE_CLASS(expr->rtype), TYPE_CLASS(type2), &depth, &isambigbase)) + ) + { + if (isambigbase) + CError_Error(CErrorStr188); + if (flag1) + CClass_CheckPathAccess(path, NULL, ACCESSPUBLIC); + + if (pathcheckflag) { + expr = getnodeaddress(expr, 0); + expr = makemonadicnode(CExpr_ClassPointerCast(path, expr, nullcheckflag), EINDIRECT); + expr->rtype = type2; + expr->flags = qual2 & ENODE_FLAG_QUALS; + } + + return expr; + } + else { + return NULL; + } +} + +static ENode *CExpr_ClassReferenceConversion(ENode *expr, Type *type2, UInt32 qual2, Boolean pathcheckflag) { + int refcompat; + + if (CExpr_IsLValue(expr) && IS_TYPE_CLASS(type2) && IS_TYPE_CLASS(expr->rtype)) { + refcompat = CExpr_IsReferenceCompatible(type2, 0, expr->rtype, 0); + if (refcompat > 0) { + if (refcompat == 2) { + CError_ASSERT(1668, IS_TYPE_CLASS(type2) && IS_TYPE_CLASS(expr->rtype)); + expr = CExpr_DerivedToBase(expr, type2, qual2, pathcheckflag, 0, 1); + } + expr->flags = qual2 & ENODE_FLAG_QUALS; + return expr; + } + + refcompat = CExpr_IsReferenceCompatible(expr->rtype, 0, type2, 0); + if (refcompat > 0) { + expr = CClass_ClassPointerCast( + getnodeaddress(expr, 0), + TYPE_CLASS(expr->rtype), TYPE_CLASS(type2), + 1, 1, pathcheckflag + ); + CError_ASSERT(1680, IS_TYPE_POINTER_ONLY(expr->rtype)); + expr = makemonadicnode(expr, EINDIRECT); + expr->rtype = type2; + expr->flags = qual2 & ENODE_FLAG_QUALS; + return expr; + } + } + + if (IS_TYPE_CLASS(expr->rtype)) { + if ((expr = CExpr_UserConversion(expr, type2, qual2, NULL, 1, 0, 1))) + return expr; + } + + return NULL; +} + +static ENode *CExpr_BindToReference(ENode *expr, Type *type2, UInt32 qual2) { + UInt32 cv; + int refcompat; + ENode *tmp; + + cv = CParser_GetCVTypeQualifiers(type2, qual2); + + if (CExpr_IsLValue(expr)) { + refcompat = CExpr_IsReferenceCompatible(type2, qual2, expr->rtype, ENODE_QUALS(expr)); + if (refcompat > 0) { + if (refcompat == 2) { + CError_ASSERT(1718, IS_TYPE_CLASS(type2) && IS_TYPE_CLASS(expr->rtype)); + expr = CExpr_DerivedToBase(expr, type2, qual2, 1, 0, 1); + } + return getnodeaddress(expr, 0); + } + } else if (IS_TYPE_CLASS(type2) && IS_TYPE_CLASS(expr->rtype)) { + refcompat = CExpr_IsReferenceCompatible(type2, qual2, expr->rtype, ENODE_QUALS(expr)); + if (refcompat > 0) { + if (refcompat == 2) + expr = CExpr_DerivedToBase(expr, type2, qual2, 1, 0, 1); + return getnodeaddress(expr, 0); + } + } + + if (IS_TYPE_CLASS(expr->rtype)) { + if ((tmp = CExpr_UserConversion(expr, type2, qual2, NULL, 1, 0, 1))) + return getnodeaddress(tmp, 0); + } + + if (!(cv & Q_CONST)) + CError_Error(CErrorStr228); + if (cv & Q_VOLATILE) + CError_Error(CErrorStr259); + + if (expr->rtype != type2) + expr = CExpr_Convert(expr, type2, qual2, 0, 1); + + if (!CExpr_IsLValue(expr)) { + expr = CExpr_LValue(expr, 0, 0); + if (!ENODE_IS(expr, EINDIRECT)) + expr = get_address_of_temp_copy(expr, 1); + else + expr = getnodeaddress(expr, 0); + } else { + expr = getnodeaddress(expr, 0); + } + + return expr; +} + +ENode *CExpr_Convert(ENode *expr, Type *type, UInt32 qual, Boolean isExplicit, Boolean flag2) { + UInt32 cv; + ENode *refExpr; + ENode *newExpr; + Type *typeCopy; + NameSpaceObjectList myList; + + cv = qual & Q_CV; + + if (copts.cpp_extensions && is_typesame(expr->rtype, type) && !ENODE_IS(expr, EOBJLIST)) { + expr = CExpr_RewriteConst(expr); + expr->rtype = type; + expr->flags &= ~ENODE_FLAG_QUALS; + expr->flags |= cv; + return expr; + } + + if (type == TYPE(&stvoid)) { + expr = makemonadicnode(expr, ETYPCON); + expr->rtype = type; + expr->flags = cv; + return expr; + } + + if (IS_TYPE_REFERENCE(type)) { + if (isExplicit) { + refExpr = CExpr_ClassReferenceConversion(expr, TPTR_TARGET(type), qual, flag2); + if (refExpr) + return refExpr; + + expr = getnodeaddress(expr, 0); + typeCopy = galloc(sizeof(TypePointer)); + *TYPE_POINTER(typeCopy) = *TYPE_POINTER(type); + TPTR_QUAL(typeCopy) &= ~Q_REFERENCE; + expr = CExpr_Convert(expr, typeCopy, qual, 0, flag2); + expr = makemonadicnode(expr, EINDIRECT); + expr->rtype = TPTR_TARGET(type); + expr->flags = cv; + return expr; + } else { + return CExpr_BindToReference(expr, TPTR_TARGET(type), qual); + } + } + + if ( + (IS_TYPE_ARRAY(expr->rtype) && !IS_TYPE_ARRAY(type)) || + (IS_TYPE_FUNC(expr->rtype) && !IS_TYPE_FUNC(type)) + ) + { + expr = pointer_generation(expr); + } else { + expr = CExpr_RewriteConst(expr); + } + + if (ENODE_IS(expr, EOBJLIST)) { + if (CExpr_OverloadFuncMatch(expr->data.objlist.list, expr->data.objlist.templargs, type, &refExpr)) + return refExpr; + } else if (ENODE_IS(expr, EOBJREF) && IS_TEMPL_FUNC(expr->data.objref->type)) { + myList.next = NULL; + myList.object = OBJ_BASE(expr->data.objref); + if (CExpr_OverloadFuncMatch(&myList, NULL, type, &refExpr)) + return refExpr; + } else if (IS_TYPE_CLASS(expr->rtype) || IS_TYPE_CLASS(type)) { + if (expr->rtype->size == 0) + CDecl_CompleteType(expr->rtype); + + if (IS_TYPE_CLASS(type)) { + CanAllocObject(type); + if (!CClass_CopyConstructor(TYPE_CLASS(type)) || CClass_IsTrivialCopyClass(TYPE_CLASS(type))) { + if (expr->rtype == type) + return expr; + + refExpr = CExpr_DerivedToBase(expr, type, qual, flag2, 0, 1); + if (refExpr) + return refExpr; + } + } + + refExpr = CExpr_UserConversion(expr, type, qual, NULL, 1, isExplicit, 0); + if (refExpr) { + refExpr->flags = cv; + return refExpr; + } + } else if (!isExplicit && is_typesame(expr->rtype, type)) { + if (ENODE_IS(expr, EINDIRECT) && ENODE_QUALS(expr) != cv) + expr = makemonadicnode(expr, ETYPCON); + expr->rtype = type; + expr->flags = cv; + return expr; + } else { + if ( + copts.warn_implicitconv && + !isExplicit && + IS_TYPE_INT_OR_FLOAT(type) && + IS_TYPE_INT_OR_FLOAT(expr->rtype) + ) + CExpr_CheckArithmConversion(expr, type); + + switch (type->type) { + case TYPEINT: + if (type == TYPE(&stbool)) { + switch (expr->rtype->type) { + case TYPEINT: + case TYPEFLOAT: + case TYPEENUM: + case TYPEMEMBERPOINTER: + case TYPEPOINTER: + return CExpr_ConvertToBool(expr, isExplicit); + } + } else { + switch (expr->rtype->type) { + case TYPEENUM: + expr->rtype = TYPE_ENUM(expr->rtype)->enumtype; + case TYPEINT: + case TYPEFLOAT: + do_int_float_conversion: + if ( + ENODE_IS(expr, ETYPCON) && + expr->rtype->type == type->type && + expr->rtype->size == type->size && + is_unsigned(expr->rtype) == is_unsigned(type) && + ENODE_QUALS(expr) == qual + ) + { + expr->rtype = type; + expr->flags |= ENODE_FLAG_80; + return expr; + } else { + refExpr = promote(expr, type); + refExpr->flags = cv; + return refExpr; + } + break; + case TYPEPOINTER: + if (expr->rtype->size > type->size && copts.warn_ptr_int_conv) + CError_Warning(CErrorStr382); + if (ENODE_IS(expr, ETYPCON)) { + ENode *inner = expr->data.monadic; + if (ENODE_IS(inner, EINTCONST)) { + inner->rtype = type; + inner->flags = cv; + inner->data.intval = CExpr_IntConstConvert(type, TYPE(&stunsignedlong), inner->data.intval); + return inner; + } + } + if (type->size != 4) { + expr = makemonadicnode(expr, ETYPCON); + expr->rtype = TYPE(&stunsignedlong); + } + expr = makemonadicnode(expr, ETYPCON); + expr->rtype = type; + expr->flags = cv; + return expr; + } + } + break; + + case TYPEFLOAT: + switch (expr->rtype->type) { + case TYPEENUM: + expr->rtype = TYPE_ENUM(expr->rtype)->enumtype; + case TYPEINT: + case TYPEFLOAT: + goto do_int_float_conversion; + } + break; + + case TYPEENUM: + expr = CExpr_Convert(expr, TYPE_ENUM(type)->enumtype, qual, isExplicit, flag2); + if (!ENODE_IS(expr, EINTCONST)) + expr = makemonadicnode(expr, ETYPCON); + expr->rtype = type; + expr->flags = cv; + return expr; + + case TYPEPOINTER: + switch (expr->rtype->type) { + case TYPEENUM: + expr->rtype = TYPE_ENUM(expr->rtype)->enumtype; + case TYPEINT: + if (expr->rtype->size != 4) { + if (!ENODE_IS(expr, EINTCONST)) + expr = makemonadicnode(expr, ETYPCON); + expr->rtype = TYPE(&stunsignedlong); + } + expr = makemonadicnode(expr, ETYPCON); + expr->rtype = type; + expr->flags = cv; + return expr; + + case TYPEPOINTER: + if (IS_TYPE_CLASS(TPTR_TARGET(expr->rtype)) && IS_TYPE_CLASS(TPTR_TARGET(type))) + expr = CExpr_SafeClassPointerCast(expr, TYPE_CLASS(TPTR_TARGET(expr->rtype)), TYPE_CLASS(TPTR_TARGET(type)), 1, flag2); + if (!ENODE_IS(expr, ETYPCON)) + expr = makemonadicnode(expr, ETYPCON); + expr->rtype = type; + expr->flags = cv; + return expr; + } + break; + + case TYPEMEMBERPOINTER: + if (!IS_TYPE_MEMBERPOINTER(expr->rtype)) + expr = CExpr_MemberPointerConversion(expr, TYPE_MEMBER_POINTER(type), 1); + + if (IS_TYPE_MEMBERPOINTER(expr->rtype)) { + expr = PointerToMemberCast(expr, TYPE_MEMBER_POINTER(expr->rtype), TYPE_MEMBER_POINTER(type), flag2); + expr->flags = cv; + return expr; + } + break; + } + } + + if (isExplicit) { + if ((newExpr = CodeGen_HandleTypeCast(expr, type, qual))) + return newExpr; + } + + CError_Error( + isExplicit ? CErrorStr247 : CErrorStr209, + expr->rtype, ENODE_QUALS(expr), + type, qual); + return nullnode(); +} + +ENode *CExpr_AssignmentPromotion(ENode *expr, Type *type2, UInt32 qual2, Boolean flag) { + ImplicitConv result; + + if (copts.old_argmatch) + return oldassignmentpromotion(expr, type2, qual2, flag); + + if (ENODE_IS(expr, EMEMBER)) + expr = getpointertomemberfunc(expr, type2, 1); + + if (!CExpr_ImplicitConversionMatch(expr, type2, qual2, &result)) { + CError_Error(CErrorStr209, expr->rtype, ENODE_QUALS(expr), type2, qual2); + return nullnode(); + } + + return CExpr_Convert(expr, type2, qual2, 0, flag); +} + +static Boolean CExpr_IsBetterMatch(Match *a, Match *b, int count) { + ImplicitConv *convA; + ImplicitConv *convB; + int i; + Boolean flag; + + convA = a->conv; + convB = b->conv; + flag = 0; + + if (convA->type != ICT_0 && convB->type != ICT_0) { + if (CExpr_IsBetterImplicitConv(convB, convA)) + return 0; + if (CExpr_IsBetterImplicitConv(convA, convB)) + flag = 1; + } + + for (i = 0; i < count; i++) { + if (CExpr_IsBetterImplicitConv(++convB, ++convA)) + return 0; + if (CExpr_IsBetterImplicitConv(convA, convB)) + flag = 1; + } + + if (flag) + return 1; + + if (b->object) { + CError_ASSERT(2165, IS_TYPE_FUNC(b->object->type)); + if (b->object->u.func.inst) { + if (!a->object) + return 1; + + CError_ASSERT(2169, IS_TYPE_FUNC(a->object->type)); + if (!a->object->u.func.inst) + return 1; + + CError_ASSERT(2174, a->specialfunc && b->specialfunc); + if (CTempl_FuncIsMoreSpecialized(a->specialfunc, b->specialfunc)) + return 1; + } + } + + return 0; +} + +static Boolean CExpr_MatchArgs(Object *func, ENodeList *argexprs, ENode *expr, ImplicitConv *convs) { + FuncArg *args; + ENode *newExpr; + Type *type; + + args = TYPE_FUNC(func->type)->args; + + if (!(TYPE_FUNC(func->type)->flags & FUNC_FLAGS_METHOD)) { + convs->type = ICT_0; + } else if (TYPE_METHOD(func->type)->x26) { + convs->type = ICT_0; + } else if (TYPE_FUNC(func->type)->flags & FUNC_FLAGS_1000) { + convs->type = ICT_0; + args = args->next; + } else { + if (!expr) + return 0; + + newExpr = lalloc(sizeof(ENode)); + newExpr->type = EINTCONST; + newExpr->cost = 0; + newExpr->flags = expr->flags; + newExpr->rtype = CDecl_NewPointerType(expr->rtype); + newExpr->data.intval = cint64_zero; + + if (func->datatype == DALIAS) { + CError_ASSERT(2231, func->u.alias.member); + type = CDecl_NewPointerType(func->u.alias.member->type); + } else { + type = args->type; + } + + if (!CExpr_ImplicitConversionMatch(newExpr, type, args->qual, convs)) + return 0; + args = args->next; + } + + convs++; + while (1) { + if (!args || args->type == &stvoid) { + if (argexprs) + return 0; + else + return 1; + } + + if (args == &elipsis || args == &oldstyle) { + while (argexprs) { + convs->type = ICT_1; + argexprs = argexprs->next; + convs++; + } + return 1; + } + + if (!argexprs) + return args->dexpr != NULL; + + if (!CExpr_ImplicitConversionMatch(argexprs->node, args->type, args->qual, convs)) + return 0; + + argexprs = argexprs->next; + args = args->next; + convs++; + } +} + +static Object *CExpr_GetMatchObject(Match *match, HashNameNode *name) { + Object *object; + FuncArg *arg; + TypeFunc *tfunc; + + if (match->object) + return match->object; + + tfunc = lalloc(sizeof(TypeFunc)); + memclrw(tfunc, sizeof(TypeFunc)); + tfunc->type = TYPEFUNC; + tfunc->functype = &stvoid; + + arg = lalloc(sizeof(FuncArg)); + memclrw(arg, sizeof(FuncArg)); + arg->type = match->type; + arg->qual = match->qual; + tfunc->args = arg; + + if (match->type2) { + arg = lalloc(sizeof(FuncArg)); + memclrw(arg, sizeof(FuncArg)); + arg->type = match->type2; + arg->qual = match->qual2; + tfunc->args->next = arg; + } + + object = lalloc(sizeof(Object)); + memclrw(object, sizeof(Object)); + object->name = name; + object->datatype = DFUNC; + object->nspace = cscope_root; + object->type = TYPE(tfunc); + return object; +} + +static Match *CExpr_FindBestMatch(Match *matches, int count, HashNameNode *name, ObjectList **outList, ENodeList *argExprs) { + Match *scan; + Match *best; + ObjectList *listHead; + ObjectList *list; + + best = matches; + for (scan = matches->next; scan; scan = scan->next) { + if (CExpr_IsBetterMatch(scan, best, count)) + best = scan; + } + + for (scan = matches, listHead = NULL; scan; scan = scan->next) { + if (scan != best && !CExpr_IsBetterMatch(best, scan, count)) { + list = lalloc(sizeof(ObjectList)); + list->next = listHead; + list->object = CExpr_GetMatchObject(scan, name); + listHead = list; + } + } + + if (!outList) { + if (listHead) + CError_OverloadedFunctionError(CExpr_GetMatchObject(best, name), listHead); + } else { + *outList = listHead; + } + + return best; +} + +void CExpr_FuncArgMatch(NameSpaceObjectList *list, TemplArg *templargs, ENodeList *argexprs, Match13 *match13, ENode *expr, Boolean flag) { + NameSpaceObjectList *i; + NameSpaceObjectList *j; + Match *match; + Match *matches; + Object *object; + Object *object2; + Object *specialfunc; + ENodeList *argscan; + int argcount; + + for (argscan = argexprs, argcount = 0; argscan; argscan = argscan->next) { + CDecl_CompleteType(argscan->node->rtype); + argcount++; + } + + matches = NULL; + match = lalloc(sizeof(Match) + ((argcount - 2) * sizeof(ImplicitConv))); + + for (i = list; i; i = i->next) { + object = OBJECT(i->object); + if ( + object->otype == OT_OBJECT && + IS_TYPE_FUNC(object->type) && + (!flag || !(object->qual & Q_EXPLICIT)) + ) + { + if (object->datatype == DALIAS && (TYPE_FUNC(object->type)->flags & FUNC_FLAGS_METHOD)) { + for (j = list; j; j = j->next) { + if (j == i) + continue; + + object2 = OBJECT(j->object); + if ( + object2->otype == OT_OBJECT && + IS_TYPE_METHOD(object2->type) && + (TYPE_FUNC(object2->type)->flags & FUNC_FLAGS_CV) == (TYPE_FUNC(object->type)->flags & FUNC_FLAGS_CV) + ) + { + FuncArg *argsA; + FuncArg *argsB; + argsA = TYPE_FUNC(object->type)->args; + if (argsA && !TYPE_METHOD(object->type)->x26) + argsA = argsA->next; + argsB = TYPE_FUNC(object2->type)->args; + if (argsB && !TYPE_METHOD(object2->type)->x26) + argsB = argsB->next; + if (is_arglistsame(argsA, argsB)) + break; + } + } + + if (j) + continue; + } + + if (TYPE_FUNC(object->type)->flags & FUNC_FLAGS_100000) { + specialfunc = object; + object = CTempl_DeduceFromFunctionCall(object, templargs, argexprs); + if (!object) + continue; + } else { + if (templargs) + continue; + specialfunc = NULL; + } + + if (CExpr_MatchArgs(object, argexprs, expr, match->conv)) { + match->object = object; + match->specialfunc = specialfunc; + match->next = matches; + matches = match; + match = lalloc(sizeof(Match) + ((argcount - 2) * sizeof(ImplicitConv))); + } + } + } + + if (matches) { + matches = CExpr_FindBestMatch(matches, argcount, NULL, &match13->list, argexprs); + match13->obj = matches->object; + } +} + +static ConversionTypeList *CExpr_BuildConversionTypeList(ENode *expr) { + ConversionTypeList *first; + ConversionTypeList *list; + Object *object; + Type *type; + ConversionIterator convIter; + + if (!IS_TYPE_CLASS(expr->rtype)) { + first = lalloc(sizeof(ConversionTypeList)); + first->next = NULL; + first->func = NULL; + first->type = expr->rtype; + first->qual = ENODE_QUALS(expr); + if (IS_TYPE_ENUM(first->type)) + first->qual = 0; + } else { + first = NULL; + CExpr_ConversionIteratorInit(&convIter, TYPE_CLASS(expr->rtype)); + while ((object = CExpr_ConversionIteratorNext(&convIter))) { + type = TYPE_FUNC(object->type)->functype; + if (IS_TYPE_REFERENCE(type)) + type = TPTR_TARGET(type); + + if (!IS_TYPE_CLASS(type)) { + list = lalloc(sizeof(ConversionTypeList)); + list->next = first; + list->func = object; + list->type = type; + list->qual = TYPE_FUNC(object->type)->qual & Q_CV; + first = list; + } + } + } + + return first; +} + +static Type *CExpr_NextPromotedIntegralType(int *p) { + switch (++(*p)) { + case 1: return TYPE(&stsignedint); + case 2: return TYPE(&stunsignedint); + case 3: return TYPE(&stsignedlong); + case 4: return TYPE(&stunsignedlong); + case 5: + if (copts.longlong) + return TYPE(&stsignedlonglong); + else + return NULL; + case 6: + if (copts.longlong) + return TYPE(&stunsignedlonglong); + else + return NULL; + } + + return NULL; +} + +static Type *CExpr_NextArithmeticType(int *p) { + switch (++(*p)) { + case 1: return TYPE(&stbool); + case 2: return TYPE(&stchar); + case 3: return TYPE(&stsignedchar); + case 4: return TYPE(&stunsignedchar); + case 5: return TYPE(&stwchar); + case 6: return TYPE(&stsignedshort); + case 7: return TYPE(&stunsignedshort); + case 8: return TYPE(&stsignedint); + case 9: return TYPE(&stunsignedint); + case 10: return TYPE(&stsignedlong); + case 11: return TYPE(&stunsignedlong); + case 12: return TYPE(&stfloat); + case 13: return TYPE(&stdouble); + case 14: return TYPE(&stlongdouble); + case 15: + if (copts.longlong) + return TYPE(&stsignedlonglong); + else + return NULL; + case 16: + if (copts.longlong) + return TYPE(&stunsignedlonglong); + else + return NULL; + } + + return NULL; +} + +static Type *CExpr_NextPromotedArithmeticType(int *p) { + switch (++(*p)) { + case 1: return TYPE(&stsignedint); + case 2: return TYPE(&stunsignedint); + case 3: return TYPE(&stsignedlong); + case 4: return TYPE(&stunsignedlong); + case 5: return TYPE(&stdouble); + case 6: return TYPE(&stlongdouble); + case 7: + if (copts.longlong) + return TYPE(&stsignedlonglong); + else + return NULL; + case 8: + if (copts.longlong) + return TYPE(&stunsignedlonglong); + else + return NULL; + } + + return NULL; +} + +static Match *CExpr_MatchBuiltin(Match *matches, ENode *left, Type *leftType, UInt32 leftQual, ENode *right, Type *rightType, UInt32 rightQual) { + Match *scan; + Match mymatch; + + if (CExpr_ImplicitConversionMatch(left, leftType, leftQual, &mymatch.conv[0])) { + if (!right || CExpr_ImplicitConversionMatch(right, rightType, rightQual, &mymatch.conv[1])) { + if (right) { + for (scan = matches; scan; scan = scan->next) { + if ( + !scan->object && + is_typesame(scan->type, leftType) && + scan->qual == leftQual && + is_typesame(scan->type2, rightType) && + scan->qual2 == rightQual + ) + return matches; + } + } + + mymatch.next = matches; + mymatch.object = NULL; + mymatch.specialfunc = NULL; + mymatch.type = leftType; + mymatch.qual = leftQual; + mymatch.type2 = rightType; + mymatch.qual2 = rightQual; + + matches = lalloc(sizeof(Match)); + *matches = mymatch; + } + } + + return matches; +} + +static Match *CExpr_CheckIncDecBuiltin(Match *matches, short token, ENode *expr1, ENode *expr2) { + Object *object; + Type *type; + TypeFunc *tfunc; + ConversionIterator convIter; + + if (IS_TYPE_CLASS(expr1->rtype)) { + CExpr_ConversionIteratorInit(&convIter, TYPE_CLASS(expr1->rtype)); + while ((object = CExpr_ConversionIteratorNext(&convIter))) { + tfunc = TYPE_FUNC(object->type); + if (IS_TYPE_REFERENCE(tfunc->functype)) { + type = TPTR_TARGET(tfunc->functype); + switch (type->type) { + case TYPEINT: + if (type == TYPE(&stbool) && token == TK_DECREMENT) + break; + case TYPEFLOAT: + case TYPEPOINTER: + if (!CParser_IsConst(type, tfunc->qual)) { + matches = CExpr_MatchBuiltin( + matches, + expr1, type, tfunc->qual, + expr2, expr2 ? TYPE(&stsignedint) : NULL, 0 + ); + } + break; + } + } + } + } + + return matches; +} + +static Match *CExpr_CheckUnaryBuiltin(Match *matches, short token, ENode *expr) { + ConversionTypeList *typelist; + Type *type; + int typenum; + + switch (token) { + case TK_INCREMENT: + case TK_DECREMENT: + return CExpr_CheckIncDecBuiltin(matches, token, expr, NULL); + + case '!': + matches = CExpr_MatchBuiltin(matches, expr, TYPE(&stbool), 0, NULL, NULL, 0); + break; + + case '~': + typenum = 0; + while ((type = CExpr_NextPromotedIntegralType(&typenum))) { + matches = CExpr_MatchBuiltin(matches, expr, type, 0, NULL, NULL, 0); + } + break; + + case '*': + case '+': + for (typelist = CExpr_BuildConversionTypeList(expr); typelist; typelist = typelist->next) { + if (IS_TYPE_POINTER_ONLY(typelist->type)) + matches = CExpr_MatchBuiltin(matches, expr, typelist->type, typelist->qual, NULL, NULL, 0); + } + if (token != '+') + break; + + case '-': + typenum = 0; + while ((type = CExpr_NextPromotedArithmeticType(&typenum))) { + matches = CExpr_MatchBuiltin(matches, expr, type, 0, NULL, NULL, 0); + } + break; + } + + return matches; +} + +static Match *CExpr_CheckBinaryBuiltin(Match *matches, ENode *left, short token, ENode *right) { + int typenum1; + int typenum2; + Type *type1; + Type *type2; + Type *ptrdiff; + Boolean allowPtrDiffOnRight; + Boolean allowPtrCV; + Boolean allowPtrDiffOnLeft; + Boolean allowMemberPtrs; + Boolean allowEnum; + ConversionTypeList *leftList; + ConversionTypeList *rightList; + ConversionTypeList *scan; + + switch (token) { + case TK_INCREMENT: + case TK_DECREMENT: + return CExpr_CheckIncDecBuiltin(matches, token, left, right); + + case '*': + case '+': + case '-': + case '/': + case ':': + case '<': + case '>': + case TK_LOGICAL_EQ: + case TK_LOGICAL_NE: + case TK_LESS_EQUAL: + case TK_GREATER_EQUAL: + typenum1 = 0; + while ((type1 = CExpr_NextPromotedArithmeticType(&typenum1))) { + typenum2 = 0; + while ((type2 = CExpr_NextPromotedArithmeticType(&typenum2))) { + matches = CExpr_MatchBuiltin(matches, left, type1, 0, right, type2, 0); + } + } + break; + + case '%': + case '&': + case '^': + case '|': + case TK_SHL: + case TK_SHR: + typenum1 = 0; + while ((type1 = CExpr_NextPromotedIntegralType(&typenum1))) { + typenum2 = 0; + while ((type2 = CExpr_NextPromotedIntegralType(&typenum2))) { + matches = CExpr_MatchBuiltin(matches, left, type1, 0, right, type2, 0); + } + } + return matches; + + case TK_LOGICAL_OR: + case TK_LOGICAL_AND: + return CExpr_MatchBuiltin(matches, left, TYPE(&stbool), 0, right, TYPE(&stbool), 0); + } + + allowEnum = 0; + allowMemberPtrs = 0; + allowPtrCV = 0; + allowPtrDiffOnLeft = 0; + allowPtrDiffOnRight = 0; + + switch (token) { + case '+': + case '[': + allowPtrDiffOnLeft = 1; + allowPtrDiffOnRight = 1; + break; + case '-': + allowPtrCV = 1; + allowPtrDiffOnRight = 1; + break; + case ':': + case TK_LOGICAL_EQ: + case TK_LOGICAL_NE: + allowMemberPtrs = 1; + case '<': + case '>': + case TK_LESS_EQUAL: + case TK_GREATER_EQUAL: + allowPtrCV = 1; + allowEnum = 1; + break; + default: + return matches; + } + + leftList = CExpr_BuildConversionTypeList(left); + rightList = CExpr_BuildConversionTypeList(right); + ptrdiff = CABI_GetPtrDiffTType(); + + for (scan = leftList; ; scan = scan->next) { + if (!scan) { + scan = rightList; + if (!rightList) + break; + rightList = NULL; + } + + type1 = scan->type; + if (IS_TYPE_REFERENCE(type1)) + type1 = TPTR_TARGET(type1); + + switch (type1->type) { + case TYPEENUM: + if (allowEnum) + matches = CExpr_MatchBuiltin(matches, left, type1, scan->qual, right, type1, scan->qual); + break; + + case TYPEPOINTER: + if (allowPtrDiffOnRight) + matches = CExpr_MatchBuiltin(matches, left, type1, scan->qual, right, ptrdiff, 0); + if (allowPtrDiffOnLeft) + matches = CExpr_MatchBuiltin(matches, left, ptrdiff, 0, right, type1, scan->qual); + if (allowPtrCV) { + if (IS_TYPE_POINTER_ONLY(TPTR_TARGET(type1))) { + type2 = galloc(sizeof(TypePointer)); + *TYPE_POINTER(type2) = *TYPE_POINTER(type1); + TPTR_QUAL(type2) |= Q_CONST | Q_VOLATILE; + matches = CExpr_MatchBuiltin(matches, left, type2, scan->qual, right, type2, scan->qual); + } else { + matches = CExpr_MatchBuiltin(matches, left, type1, Q_CONST | Q_VOLATILE, right, type1, Q_CONST | Q_VOLATILE); + } + } + break; + + case TYPEMEMBERPOINTER: + if (allowMemberPtrs) + matches = CExpr_MatchBuiltin(matches, left, type1, scan->qual, right, type1, scan->qual); + break; + } + } + + return matches; +} + +static Boolean CExpr_MatchOperands(ENode *left, Type *leftType, UInt32 leftQual, ENode *right, Type *rightType, UInt32 rightQual, ImplicitConv *twoResults, Boolean flag) { + if (flag) { + if (!CExpr_StandardConversionMatch(left, leftType, leftQual, 1, &twoResults[0].u.ic3.standardConv)) + return 0; + twoResults[0].type = ICT_3; + } else { + if (!CExpr_ImplicitConversionMatch(left, leftType, leftQual, &twoResults[0])) + return 0; + } + + if (right) { + if (!CExpr_ImplicitConversionMatch(right, rightType, rightQual, &twoResults[1])) + return 0; + } + + return 1; +} + +Boolean CExpr_CondOperatorMatch(ENode *left, ENode *right, Conversion *conv) { + Match *match; + + if ((match = CExpr_CheckBinaryBuiltin(NULL, left, ':', right))) { + match = CExpr_FindBestMatch(match, 1, GetHashNameNode("operator?:"), NULL, NULL); + CError_ASSERT(2931, !match->object); + + conv->x0 = NULL; + conv->left = CExpr_Convert(left, match->type, match->qual, 0, 1); + conv->right = CExpr_Convert(right, match->type2, match->qual2, 0, 1); + return 1; + } + + return 0; +} + +Boolean CExpr_OperatorMatch(short token, ENode *left, ENode *right, Conversion *conv) { + HashNameNode *name; + ENodeList *argExprs; + BClassList *path; + int hasArg; + Match *matches; + Object *object; + Object *specialfunc; + NameSpaceObjectList *list; + Type *leftType; + UInt32 leftQual; + Type *rightType; + UInt32 rightQual; + CScopeParseResult pr; + NameSpaceObjectList myList; + Match myMatch; + + if (!IS_TYPE_CLASS(left->rtype)) { + if (!IS_TYPE_ENUM(left->rtype)) { + if (!right || !(IS_TYPE_CLASS(right->rtype) || IS_TYPE_ENUM(right->rtype))) + return 0; + } + } else { + CDecl_CompleteType(left->rtype); + } + + name = CMangler_OperatorName(token); + path = NULL; + + argExprs = lalloc(sizeof(ENodeList)); + argExprs->node = left; + if (right) { + argExprs->next = lalloc(sizeof(ENodeList)); + argExprs->next->node = right; + argExprs->next->next = NULL; + hasArg = 1; + } else { + argExprs->next = NULL; + hasArg = 0; + } + + matches = NULL; + + if (IS_TYPE_CLASS(left->rtype) && CScope_FindClassMemberObject(TYPE_CLASS(left->rtype), &pr, name)) { + if (token != '=' || (pr.bcl_18->type == left->rtype && !pr.bcl_18->next)) { + if (pr.obj_10) { + myList.next = NULL; + myList.object = pr.obj_10; + pr.nsol_14 = &myList; + } else { + CError_ASSERT(3009, pr.nsol_14); + } + + for (list = pr.nsol_14; list; list = list->next) { + object = OBJECT(list->object); + if (object->otype == OT_OBJECT && IS_TYPE_FUNC(object->type)) { + if (TYPE_FUNC(object->type)->flags & FUNC_FLAGS_100000) { + specialfunc = object; + object = CTempl_DeduceFromFunctionCall(object, NULL, argExprs->next); + if (!object) + continue; + } else { + specialfunc = NULL; + } + + leftType = CExpr_GetImplictObjectParamType(object, &leftQual); + if (right) { + if (!CExpr_HasNParams(object, 1)) + continue; + rightType = CExpr_GetParamType(object, 0, &rightQual); + } else { + if (!CExpr_HasNParams(object, 0)) + continue; + } + + if (CExpr_MatchOperands(left, leftType, leftQual, right, rightType, rightQual, myMatch.conv, 1)) { + myMatch.object = object; + myMatch.specialfunc = specialfunc; + myMatch.next = matches; + matches = lalloc(sizeof(Match)); + *matches = myMatch; + path = pr.bcl_18; + } + } + } + } + } + + if (CScope_FindNonClassObject(cscope_current, &pr, name)) { + if (pr.obj_10) { + myList.next = NULL; + myList.object = pr.obj_10; + pr.nsol_14 = &myList; + } + } else { + pr.nsol_14 = NULL; + } + + if (copts.arg_dep_lookup) + pr.nsol_14 = CScope_ArgumentDependentNameLookup(pr.nsol_14, name, argExprs, 1); + + for (list = pr.nsol_14; list; list = list->next) { + object = OBJECT(list->object); + if (object->otype == OT_OBJECT && IS_TYPE_NONMETHOD(object->type)) { + if (TYPE_FUNC(object->type)->flags & FUNC_FLAGS_100000) { + specialfunc = object; + object = CTempl_DeduceFromFunctionCall(object, NULL, argExprs); + if (!object) + continue; + } else { + specialfunc = NULL; + } + + leftType = CExpr_GetParamType(object, 0, &leftQual); + if (right) { + if (!CExpr_HasNParams(object, 2)) + continue; + rightType = CExpr_GetParamType(object, 1, &rightQual); + } else { + if (!CExpr_HasNParams(object, 1)) + continue; + } + + if (CExpr_MatchOperands(left, leftType, leftQual, right, rightType, rightQual, myMatch.conv, 0)) { + myMatch.object = object; + myMatch.specialfunc = specialfunc; + myMatch.next = matches; + matches = lalloc(sizeof(Match)); + *matches = myMatch; + } + } + } + + if (right) + matches = CExpr_CheckBinaryBuiltin(matches, left, token, right); + else + matches = CExpr_CheckUnaryBuiltin(matches, token, left); + + if (matches) { + conv->x0 = NULL; + conv->left = NULL; + conv->right = NULL; + + matches = CExpr_FindBestMatch(matches, hasArg, name, NULL, argExprs); + object = matches->object; + if (!object) { + if (IS_TYPE_CLASS(left->rtype)) + conv->left = CExpr_Convert(left, matches->type, matches->qual, 0, 1); + else + conv->left = left; + + if (right) { + if (IS_TYPE_CLASS(right->rtype)) + conv->right = CExpr_Convert(right, matches->type2, matches->qual2, 0, 1); + else + conv->right = right; + } + + return 1; + } + + if (IS_TYPEFUNC_NONSTATIC_METHOD(TYPE_FUNC(object->type))) { + CError_ASSERT(3125, path); + left = CExpr_GenericFuncCall(path, argExprs->node, 0, object, NULL, NULL, argExprs->next, 0, 0, 1); + } else { + left = CExpr_GenericFuncCall(NULL, NULL, 0, object, NULL, NULL, argExprs, 0, 0, 1); + } + + conv->x0 = checkreference(left); + return 1; + } + + return 0; +} + +static ENode *CExpr_ClassCopyInit(TypeClass *tclass, ENode *expr1, ENode *expr2) { + Object *best; + NameSpaceObjectList *list; + ObjectList *objlist; + ObjectList *objlistEntry; + ENodeList *argExprs; + FuncArg *arg; + Type *type; + Object *object; + ImplicitConv bestConv; + ImplicitConv conv; + BClassList path; + ConversionIterator convIter; + + best = NULL; + objlist = NULL; + + for (list = CClass_Constructor(tclass); list; list = list->next) { + object = OBJECT(list->object); + if (object->otype == OT_OBJECT && IS_TYPE_FUNC(object->type) && !(object->qual & Q_EXPLICIT)) { + arg = TYPE_FUNC(object->type)->args; + + CError_ASSERT(3199, arg); + arg = arg->next; + + if (tclass->flags & CLASS_FLAGS_20) { + CError_ASSERT(3203, arg); + arg = arg->next; + } + + if ( + arg && + arg != &elipsis && + (!arg->next || arg->next->dexpr) && + CExpr_ImplicitConversionMatch(expr2, arg->type, arg->qual, &conv) + ) + { + if (!best || CExpr_IsBetterImplicitConv(&conv, &bestConv)) { + best = object; + bestConv = conv; + objlist = NULL; + } else if (!CExpr_IsBetterImplicitConv(&bestConv, &conv)) { + objlistEntry = lalloc(sizeof(ObjectList)); + objlistEntry->next = objlist; + objlistEntry->object = object; + objlist = objlistEntry; + } + } + } + } + + if (IS_TYPE_CLASS(expr2->rtype)) { + CExpr_ConversionIteratorInit(&convIter, TYPE_CLASS(expr2->rtype)); + while ((object = CExpr_ConversionIteratorNext(&convIter))) { + type = TYPE_FUNC(object->type)->functype; + if (IS_TYPE_REFERENCE(type)) + type = TPTR_TARGET(type); + + if ( + IS_TYPE_CLASS(type) && + (tclass == TYPE_CLASS(type) || CClass_IsBaseClass(tclass, TYPE_CLASS(type), NULL, 0, 0)) + ) + { + CError_ASSERT(3248, TYPE_FUNC(object->type)->args && + IS_TYPE_POINTER_ONLY(TYPE_FUNC(object->type)->args->type)); + + type = galloc(sizeof(TypePointer)); + *TYPE_POINTER(type) = *TYPE_POINTER(TYPE_FUNC(object->type)->args->type); + TPTR_QUAL(type) = Q_REFERENCE; + if (CExpr_ImplicitConversionMatch(expr2, type, TYPE_FUNC(object->type)->args->qual, &conv)) { + if (!best || CExpr_IsBetterImplicitConv(&conv, &bestConv)) { + best = object; + bestConv = conv; + objlist = NULL; + } else if (!CExpr_IsBetterImplicitConv(&bestConv, &conv)) { + objlistEntry = lalloc(sizeof(ObjectList)); + objlistEntry->next = objlist; + objlistEntry->object = object; + objlist = objlistEntry; + } + } + } + } + } + + if (objlist) + CError_OverloadedFunctionError(best, objlist); + + if (!best) { + CError_Error(CErrorStr209, expr2->rtype, ENODE_QUALS(expr2), tclass, 0); + return expr1; + } + + CError_ASSERT(3284, IS_TYPE_POINTER_ONLY(expr1->rtype)); + + expr1 = makemonadicnode(expr1, EINDIRECT); + expr1->rtype = TYPE(tclass); + + argExprs = lalloc(sizeof(ENodeList)); + argExprs->node = expr2; + if (tclass->flags & CLASS_FLAGS_20) { + argExprs->next = lalloc(sizeof(ENodeList)); + argExprs->next->next = NULL; + argExprs->next->node = intconstnode(TYPE(&stsignedshort), 1); + } else { + argExprs->next = NULL; + } + + path.next = NULL; + path.type = TYPE(tclass); + expr1 = CExpr_GenericFuncCall(&path, expr1, 0, best, NULL, NULL, argExprs, 0, 0, 1); + + if (ENODE_IS2(expr1, EFUNCCALL, EFUNCCALLP)) + expr1->rtype = CDecl_NewPointerType(TYPE(tclass)); + + expr1 = makemonadicnode(expr1, EINDIRECT); + expr1->rtype = TYPE(tclass); + return expr1; +} diff --git a/compiler_and_linker/unsorted/CFunc.c b/compiler_and_linker/unsorted/CFunc.c index 780dbd2..94a2c9e 100644 --- a/compiler_and_linker/unsorted/CFunc.c +++ b/compiler_and_linker/unsorted/CFunc.c @@ -1,6 +1,73 @@ #include "compiler/CFunc.h" +#include "compiler/CABI.h" +#include "compiler/CClass.h" +#include "compiler/CDecl.h" +#include "compiler/CError.h" +#include "compiler/CException.h" +#include "compiler/CExpr.h" +#include "compiler/CInit.h" +#include "compiler/CInline.h" +#include "compiler/CInt64.h" +#include "compiler/CMachine.h" +#include "compiler/CMangler.h" +#include "compiler/CParser.h" +#include "compiler/CPrepTokenizer.h" +#include "compiler/CSOM.h" +#include "compiler/CTemplateTools.h" +#include "compiler/CodeGen.h" +#include "compiler/CompilerTools.h" +#include "compiler/Exceptions.h" +#include "compiler/FuncLevelAsmPPC.h" +#include "compiler/InlineAsmPPC.h" +#include "compiler/ObjGenMachO.h" +#include "compiler/Switch.h" +#include "compiler/objects.h" +#include "compiler/scopes.h" #include "compiler/types.h" +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +struct CFuncSave { + CScopeSave scope; + ObjectList *arguments; + ObjectList *locals; + CLabel *labels; + Statement *curstmt; + DeclBlock *firstblock; + DeclBlock *currentblock; + ExceptionAction *cexcept_dobjstack; + CLabel *sinit_label; + ENode *ainit_expr; + CtorChain *ctor_chain; + ParserTryBlock *trychain; + TempNodeCB cinit_tempnodefunc; + HashNameNode *tkidentifier; + Object *sinit_first_object; + FileOffsetInfo cparser_fileoffset; + TStreamElement symdecltoken; + SInt32 functionbodyoffset; + HashNameNode *functionbodypath; + SInt32 symdecloffset; + SInt32 symdeclend; + SInt32 sourceoffset; + HashNameNode *sourcefilepath; + SInt32 curstmtvalue; + NameObjCheckCB name_obj_check; + FuncArg *check_arglist; + short blockcount; + short localcount; + short tk; + AccessType global_access; + Boolean cexcept_hasdobjects; + Boolean ainit_only_one; + Boolean cfunc_is_extern_c; + Boolean temp_reference_init; +}; +#ifdef __MWERKS__ +#pragma options align=reset +#endif + FuncArg elipsis; FuncArg oldstyle; ObjectList *arguments; @@ -31,75 +98,3127 @@ static short cfunc_staticvarcount; static void *destroyobjects; static Boolean cfunc_hasdtortemp; -static void CFunc_LoopIncrement(void) {} -static void CFunc_LoopDecrement(void) {} -DeclBlock *CFunc_NewDeclBlock(void) {} -void CFunc_RestoreBlock(DeclBlock *block) {} -void CFunc_SetupLocalVarInfo(Object *obj) {} -static void adjustargumenttype(DeclInfo *declinfo) {} -static FuncArg *CFunc_IsInArgList(FuncArg *list, HashNameNode *name) {} -static Object *CFunc_IsInObjList(ObjectList *list, HashNameNode *name) {} -static void CFunc_AppendArg(FuncArg **list, FuncArg *arg) {} -static void identifier_list(DeclInfo *declinfo) {} -static Boolean defarg_name_obj_check(HashNameNode *name, Object *obj) {} -void CFunc_DefaultArg(Type *type, short qual, FuncArg *args) {} -static FuncArg *parameter_list(DeclInfo *declinfo) {} -Boolean CFunc_ParseFakeArgList(Boolean flag) {} -FuncArg *parameter_type_list(DeclInfo *declinfo) {} -CLabel *findlabel(void) {} -CLabel *newlabel(void) {} -Statement *CFunc_AppendStatement(StatementType sttype) {} -Statement *CFunc_InsertStatement(StatementType sttype, Statement *after) {} -Statement *CFunc_InsertBeforeStatement(StatementType sttype, Statement *before) {} -void CheckCLabels(void) {} -Object *create_temp_object(Type *type) {} -ENode *create_temp_node(Type *type) {} -ENode *create_temp_node2(Type *type) {} -static void CFunc_DestroyReverse() {} // not sure about type -static void CFunc_TempTransDestroy() {} // not sure about type -void CFunc_WarnUnused(void) {} -void CFunc_CodeCleanup(Statement *stmt) {} -static Boolean DestructorNeeded(ExceptionAction *a, ExceptionAction *b) {} -static Statement *DestructLocals(Statement *stmt, ExceptionAction *exc1, ExceptionAction *exc2) {} -static Boolean NeedsDestruction(Statement *stmt1, Statement *stmt2) {} -static ExceptionAction *FindLastNonCommonStackObj(Statement *stmt1, Statement *stmt2) {} -static void DestructorReturnTransform(Statement *stmt1, Statement *stmt2) {} -static Statement *DestructorIfTransform(Statement *stmt) {} -static Boolean IsSubStack(ExceptionAction *exc1, ExceptionAction *exc2) {} -static void CFunc_CheckInitSkip(Statement *stmt, ExceptionAction *exc) {} -void CFunc_DestructorCleanup(Statement *stmt) {} -static void scancase(DeclThing *thing) {} -static void CFunc_NameLocalStaticDataObject(Object *obj, char *str) {} -static void sinit_insert_expr(ENode *expr) {} -static void ainit_insert_expr(ENode *expr) {} -static ENode *ainit_register_object(TypeClass *tclass, Object *local, SInt32 offset, void *unk) {} -static void CFunc_LocalDataDeclarator(DeclInfo *declinfo, TStreamElement *element, Boolean flag1, Boolean flag2) {} -static ENode *CFunc_ParseLocalDeclarationList(Boolean flag1, Boolean flag2, Boolean flag3, Boolean flag4) {} -static void makeifstatement(ENode *expr, CLabel *label1, CLabel *label2, Boolean flag1, Boolean flag2) {} -static void CFunc_HasDtorTempCallBack(ENode *expr) {} -static void ifstatement(Boolean flag1, ENode *expr, CLabel *label, Boolean flag2) {} -Statement *CFunc_GenerateLoop(Statement *stmt, Type *type, ENode *expr1, ENode *expr2, ENode *expr3, ENode *expr4, ENode (*callback)(ENode *, ENode *)) {} -static Boolean checklabel(void) {} -static ENode *returnstatementadjust(ENode *expr, Type *type, UInt32 qual) {} -static void CFunc_AutoResultCheck(ENode *expr) {} -static void statement(DeclThing *thing) {} -void CFunc_CompoundStatement(DeclThing *thing) {} -static void CFunc_InsertArgumentCopyConversion(Object *obj, Type *type1, Type *type2, Boolean flag) {} -static void CFunc_AdjustOldStyleArgs(void) {} -void CFunc_SetupNewFuncArgs(Object *obj, FuncArg *args) {} -static ObjectList *CFunc_CopyObjectList(ObjectList *list) {} -static void SetupFunctionArguments(Object *obj, DeclInfo *declinfo) {} -NameSpace *CFunc_FuncGenSetup(Statement *stmt, Object *func) {} -void CFunc_GetGlobalCompilerState(CFuncSave *state) {} -void CFunc_SetGlobalCompilerState(CFuncSave *state) {} -void CFunc_Gen(Statement *stmt, Object *obj, UInt8 unk) {} -static void CFunc_CheckCtorInitializer(TypeClass *tclass, CtorChain *chain) {} -void CFunc_CheckClassCtors(TypeClass *tclass) {} -static void CFunc_ParseCtorInitializer(void) {} -static void CFunc_FunctionRedefinedCheck(Object *obj) {} -static Object *CFunc_DeclareFuncName(char *str, HashNameNode *name) {} -void CFunc_ParseFuncDef(Object *obj, DeclInfo *declinfo, TypeClass *tclass, Boolean is_method, Boolean is_static, NameSpace *nspace) {} -void InitExpr_Register(ENode *expr, Object *object) {} -void CFunc_GenerateDummyFunction(Object *a) {} -void CFunc_GenerateSingleExprFunc(Object *a, ENode *expr) {} -void CFunc_GenerateDummyCtorFunc(Object *a, Object *b) {} +// forward decls +static void statement(DeclThing *thing); + +static void CFunc_LoopIncrement(void) { + if (curstmtvalue >= 0x1000) { + if (curstmtvalue >= 0xF000) + curstmtvalue++; + else + curstmtvalue += 0x1000; + } else { + curstmtvalue <<= 3; + } +} + +static void CFunc_LoopDecrement(void) { + if (curstmtvalue > 0x1000) { + if (curstmtvalue > 0xF000) + curstmtvalue--; + else + curstmtvalue -= 0x1000; + } else { + curstmtvalue >>= 3; + } + + if (curstmtvalue < 1) + curstmtvalue = 1; +} + +DeclBlock *CFunc_NewDeclBlock(void) { + DeclBlock *block; + NameSpace *nspace; + + block = lalloc(sizeof(DeclBlock)); + if (firstblock) { + currentblock->next = block; + currentblock = block; + } else { + firstblock = block; + currentblock = block; + } + + block->index = blockcount++; + block->parent_nspace = cscope_current; + block->dobjstack = cexcept_dobjstack; + + nspace = CScope_NewListNameSpace(NULL, 0); + nspace->parent = cscope_current; + cscope_current = nspace; + + return block; +} + +void CFunc_RestoreBlock(DeclBlock *block) { + if (curstmt && curstmt->dobjstack != cexcept_dobjstack) { + Statement *stmt = CFunc_AppendStatement(ST_EXPRESSION); + stmt->expr = nullnode(); + } + + cscope_current = block->parent_nspace; + cexcept_dobjstack = block->dobjstack; +} + +void CFunc_SetupLocalVarInfo(Object *obj) { + obj->u.var.info = CodeGen_GetNewVarInfo(); + obj->u.var.info->func = cscope_currentfunc; + + if (obj->sclass == TK_REGISTER) { + if (!copts.optimize_for_size) + obj->u.var.info->usage = 100; + else + obj->u.var.info->usage = 5; + } + + if (obj->type && is_volatile_object(obj)) + obj->u.var.info->noregister = 1; +} + +static void adjustargumenttype(DeclInfo *declinfo) { + switch (declinfo->thetype->type) { + case TYPECLASS: + if (TYPE_CLASS(declinfo->thetype)->sominfo) { + CError_Error(CErrorStr284); + declinfo->thetype = TYPE(&stsignedint); + } + break; + case TYPEFUNC: + makethetypepointer(declinfo, 0); + return; + case TYPEARRAY: + declinfo->thetype = CDecl_NewPointerType(TPTR_TARGET(declinfo->thetype)); + return; + case TYPETEMPLATE: + if (TYPE_TEMPLATE(declinfo->thetype)->dtype == TEMPLDEP_ARRAY) + declinfo->thetype = CDecl_NewPointerType(TYPE_TEMPLATE(declinfo->thetype)->u.array.type); + return; + } + + if (!CanCreateObject(declinfo->thetype)) + declinfo->thetype = TYPE(&stsignedint); +} + +static FuncArg *CFunc_IsInArgList(FuncArg *list, HashNameNode *name) { + while (list) { + if (name == list->name) + return list; + list = list->next; + } + + return NULL; +} + +static Object *CFunc_IsInObjList(ObjectList *list, HashNameNode *name) { + while (list) { + if (name == list->object->name) + return list->object; + list = list->next; + } + + return NULL; +} + +static void CFunc_AppendArg(FuncArg **list, FuncArg *arg) { + FuncArg *tail; + + if ((tail = *list)) { + while (tail->next) + tail = tail->next; + tail->next = arg; + } else { + *list = arg; + } +} + +static void identifier_list(DeclInfo *declinfo) { + FuncArg *arg; + + declinfo->x45 = 1; + + while (1) { + if (tk != TK_IDENTIFIER) { + CError_Error(CErrorStr121); + } else { + if (CFunc_IsInArgList(declinfo->x18, tkidentifier)) + CError_Error(CErrorStr122, tkidentifier->name); + + arg = CParser_NewFuncArg(); + arg->name = tkidentifier; + CFunc_AppendArg(&declinfo->x18, arg); + declinfo->x44 = 1; + } + + if ((tk = lex()) != ',') + break; + tk = lex(); + } +} + +static Boolean defarg_name_obj_check(HashNameNode *name, Object *obj) { + FuncArg *arg; + + if (name) { + for (arg = check_arglist; arg; arg = arg->next) { + if (arg->name == name) { + CError_Error(CErrorStr205); + return 0; + } + } + } + + if (obj && obj->datatype == DLOCAL) { + CError_Error(CErrorStr205); + return 0; + } + + return 1; +} + +ENode *CFunc_DefaultArg(Type *type, UInt32 qual, FuncArg *args) { + TStreamElement *element; + ENode *expr; + ENode *templdepexpr; + + name_obj_check = defarg_name_obj_check; + check_arglist = args; + expr = conv_assignment_expression(); + name_obj_check = NULL; + + if ( + !CTemplTool_IsTemplateArgumentDependentExpression(expr) && + !CTemplTool_IsTemplateArgumentDependentType(type) + ) + { + expr = argumentpromotion(expr, type, qual, 1); + } else { + element = CPrep_CurStreamElement(); + if (element && element->tokenfile) { + templdepexpr = CExpr_NewTemplDepENode(TDE_SOURCEREF); + templdepexpr->data.templdep.u.sourceref.expr = expr; + templdepexpr->data.templdep.u.sourceref.token = galloc(sizeof(TStreamElement)); + *templdepexpr->data.templdep.u.sourceref.token = *element; + expr = templdepexpr; + } + } + + return CInline_CopyExpression(expr, CopyMode1); +} + +static FuncArg *parameter_list(DeclInfo *declinfo) { + Boolean flag26; + FuncArg *args; + FuncArg *arg; + DeclInfo my_di; + Boolean isArray; + + args = NULL; + flag26 = 1; + + while (1) { + if (tk == TK_ELLIPSIS) { + if (flag26) { + if (!copts.cplusplus && copts.ANSI_strict) + CError_Warning(CErrorStr127); + args = &elipsis; + } else { + CFunc_AppendArg(&args, &elipsis); + } + + tk = lex(); + return args; + } + + memclrw(&my_di, sizeof(my_di)); + CParser_GetDeclSpecs(&my_di, 0); + if (my_di.x48) + CError_Error(CErrorStr127); + + if ( + my_di.storageclass && + my_di.storageclass != TK_REGISTER && + (!copts.cplusplus || my_di.storageclass != TK_AUTO) + ) + { + CError_Error(CErrorStr127); + my_di.storageclass = 0; + } + + my_di.name = NULL; + + scandeclarator(&my_di); + + if (flag26) { + flag26 = 0; + if (my_di.thetype == &stvoid) { + if (my_di.storageclass || my_di.qual || my_di.name) + CError_Error(CErrorStr127); + return NULL; + } + } + + isArray = IS_TYPE_ARRAY(my_di.thetype); + adjustargumenttype(&my_di); + + if (my_di.name) { + if (args && CFunc_IsInArgList(args, my_di.name)) + CError_Error(CErrorStr122, my_di.name->name); + } else { + my_di.name = no_name_node; + } + + if (my_di.thetype == &stvoid) + CError_Error(CErrorStr126); + + arg = CParser_NewFuncArg(); + arg->name = my_di.name; + arg->type = my_di.thetype; + arg->qual = my_di.qual; + arg->sclass = my_di.storageclass; + arg->is_array = isArray; + CFunc_AppendArg(&args, arg); + + if (copts.cplusplus && tk == '=') { + tk = lex(); + arg->dexpr = CFunc_DefaultArg(arg->type, arg->qual, args); + } + + if (tk != ',') { + if (tk != TK_ELLIPSIS || !copts.cplusplus) + return args; + } else { + tk = lex(); + } + } +} + +Boolean CFunc_ParseFakeArgList(Boolean flag) { + DeclInfo di; + + if (tk == TK_ELLIPSIS) + return 1; + + do { + memclrw(&di, sizeof(di)); + CParser_GetDeclSpecs(&di, 0); + + if (di.x48) + return 0; + + scandeclarator(&di); + + if (tk == '=') { + tk = lex(); + assignment_expression(); + } + + switch (tk) { + case TK_ELLIPSIS: + return 1; + case ',': + if (!flag) + tk = lex(); + else + return 1; + break; + default: + return 0; + } + } while (tk != TK_ELLIPSIS); + + return 1; +} + +FuncArg *parameter_type_list(DeclInfo *declinfo) { + FuncArg *args; + NameSpace *nspace; + Boolean save_in_func_arglist; + + declinfo->x44 = 0; + declinfo->x45 = 0; + declinfo->x1C = NULL; + + if (tk == TK_ELLIPSIS || isdeclaration(0, 0, 0, 0)) { + if (!copts.cplusplus) { + nspace = CScope_NewListNameSpace(NULL, 0); + nspace->parent = cscope_current; + cscope_current = nspace; + + save_in_func_arglist = in_func_arglist; + in_func_arglist = 1; + args = parameter_list(declinfo); + in_func_arglist = save_in_func_arglist; + + cscope_current = nspace->parent; + + if (!CScope_IsEmptyNameSpace(nspace)) + declinfo->x1C = nspace; + } else { + args = parameter_list(declinfo); + } + } else if (copts.cplusplus) { + args = NULL; + if (tk != ')') + CError_Error(CErrorStr127); + } else { + identifier_list(declinfo); + args = &oldstyle; + } + + return args; +} + +CLabel *findlabel(void) { + CLabel *scan; + + for (scan = Labels; scan; scan = scan->next) { + if (tkidentifier == scan->name) + return scan; + } + + return NULL; +} + +CLabel *newlabel(void) { + CLabel *label = lalloc(sizeof(CLabel)); + memclrw(label, sizeof(CLabel)); + + label->name = label->uniquename = CParser_GetUniqueName(); + return label; +} + +Statement *CFunc_AppendStatement(StatementType sttype) { + Statement *stmt = lalloc(sizeof(Statement)); + + stmt->next = NULL; + stmt->type = sttype; + stmt->value = curstmtvalue; + stmt->flags = 0; + stmt->sourceoffset = sourceoffset; + stmt->sourcefilepath = sourcefilepath; + stmt->dobjstack = cexcept_dobjstack; + + curstmt->next = stmt; + curstmt = stmt; + return stmt; +} + +Statement *CFunc_InsertStatement(StatementType sttype, Statement *after) { + Statement *stmt = lalloc(sizeof(Statement)); + + stmt->next = after->next; + after->next = stmt; + stmt->type = sttype; + stmt->value = after->value; + stmt->flags = 0; + stmt->sourceoffset = after->sourceoffset; + stmt->sourcefilepath = after->sourcefilepath; + stmt->dobjstack = after->dobjstack; + + return stmt; +} + +Statement *CFunc_InsertBeforeStatement(StatementType sttype, Statement *before) { + Statement *stmt = lalloc(sizeof(Statement)); + + *stmt = *before; + before->next = stmt; + before->type = sttype; + before->flags = 0; + + return before; +} + +void CheckCLabels(void) { + CLabel *scan; + + for (scan = Labels; scan; scan = scan->next) { + if (!scan->stmt) + CError_Error(CErrorStr159, scan->name->name); + } +} + +Object *create_temp_object(Type *type) { + Object *object = CParser_NewLocalDataObject(NULL, 1); + object->name = CParser_GetUniqueName(); + object->type = type; + CFunc_SetupLocalVarInfo(object); + return object; +} + +ENode *create_temp_node(Type *type) { + ENode *node; + + if (cinit_tempnodefunc) + return cinit_tempnodefunc(type, 0); + + node = CExpr_NewETEMPNode(type, 0); + if (IS_TYPE_CLASS(type) && CClass_Destructor(TYPE_CLASS(type))) + node->data.temp.needs_dtor = 1; + return node; +} + +ENode *create_temp_node2(Type *type) { + ENode *node; + + if (cinit_tempnodefunc) + return cinit_tempnodefunc(type, 1); + + node = CExpr_NewETEMPNode(type, 0); + node->data.temp.needs_dtor = 1; + return node; +} + +static ENode *CFunc_DestroyReverse(ENode *expr, DtorTemp *list) { + expr = makediadicnode(expr, CABI_DestroyObject(list->dtor, create_objectrefnode(list->object), CABIDestroy1, 1, 0), ECOMMA); + expr->rtype = &stvoid; + if (list->next) + expr = CFunc_DestroyReverse(expr, list->next); + return expr; +} + +static ENode *CFunc_TempTransDestroy(ENode *expr, DtorTemp *list, Boolean flag) { + Object *tempobj; + + if (flag) { + CError_ASSERT(738, !(IS_TYPE_CLASS(expr->rtype) && CClass_Destructor(TYPE_CLASS(expr->rtype)))); + tempobj = create_temp_object(expr->rtype); + expr = makediadicnode(create_objectnode(tempobj), expr, EASS); + } + + expr = CFunc_DestroyReverse(expr, list); + + if (flag) { + expr = makediadicnode(expr, create_objectnode(tempobj), ECOMMA); + expr->rtype = tempobj->type; + } + + return expr; +} + +void CFunc_WarnUnused(void) { + if (copts.warn_unusedvar) { + ObjectList *list; + for (list = locals; list; list = list->next) { + if ( + !(list->object->flags & OBJECT_FLAGS_UNUSED) && + !IsTempName(list->object->name) && + !(list->object->qual & Q_10000) + ) + { + CError_SetErrorToken(&list->object->u.var.info->deftoken); + CError_Warning(CErrorStr182, &list->object->name->name); + } + } + } + + if (copts.warn_unusedarg) { + ObjectList *list; + for (list = arguments; list; list = list->next) { + if ( + !(list->object->flags & OBJECT_FLAGS_UNUSED) && + !IsTempName(list->object->name) && + list->object->name != this_name_node && + list->object->name != self_name_node + ) + { + CError_SetErrorToken(&symdecltoken); + CError_Warning(CErrorStr182, &list->object->name->name); + } + } + } +} + +void CFunc_CodeCleanup(Statement *stmt) { + if (cscope_currentclass && cscope_currentclass->sominfo) + CSOM_InitSOMSelf(cscope_currentclass, stmt); + + CFunc_WarnUnused(); + CExcept_ExceptionTansform(stmt); +} + +static Boolean DestructorNeeded(ExceptionAction *ea, ExceptionAction *end) { + while (ea) { + if (CExcept_ActionNeedsDestruction(ea)) + return 1; + if (ea == end) + break; + ea = ea->prev; + } + + return 0; +} + +static Statement *DestructLocals(Statement *stmt, ExceptionAction *ea, ExceptionAction *end) { + while (ea) { + stmt = CExcept_ActionCleanup(ea, stmt); + if (ea == end) + break; + ea = ea->prev; + } + + return stmt; +} + +static Boolean NeedsDestruction(Statement *stmt1, Statement *stmt2) { + ExceptionAction *ea2; + ExceptionAction *ea1; + ExceptionAction *scan; + + ea1 = stmt1->dobjstack; + ea2 = stmt2->dobjstack; + + for (scan = ea2; scan; scan = scan->prev) { + if (scan == ea1) + return 0; + } + + while (ea1 && ea1 != ea2) { + if (CExcept_ActionNeedsDestruction(ea1)) + return 1; + ea1 = ea1->prev; + } + + return 0; +} + +static ExceptionAction *FindLastNonCommonStackObj(Statement *stmt1, Statement *stmt2) { + ExceptionAction *ea1; + ExceptionAction *ea2; + + for (ea2 = stmt2->dobjstack; ea2; ea2 = ea2->prev) { + for (ea1 = stmt1->dobjstack; ea1; ea1 = ea1->prev) { + if (ea1->prev == ea2) + return ea1; + } + } + + return NULL; +} + +static void DestructorReturnTransform(Statement *stmt1, Statement *stmt2) { + Statement *stmt; + Object *tempobj; + + if (stmt1->dobjstack != stmt2->dobjstack && NeedsDestruction(stmt1, stmt2)) + stmt1 = DestructLocals(stmt1, stmt1->dobjstack, FindLastNonCommonStackObj(stmt1, stmt2)); + + if (DestructorNeeded(stmt2->dobjstack, NULL)) { + if (CMach_GetFunctionResultClass(TYPE_FUNC(cscope_currentfunc->type)) != 1) { + tempobj = create_temp_object(stmt2->expr->rtype); + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt1); + stmt->expr = makediadicnode(create_objectnode(tempobj), stmt2->expr, EASS); + stmt->sourceoffset = stmt2->sourceoffset; + stmt->sourcefilepath = stmt2->sourcefilepath; + DestructLocals(stmt, stmt2->dobjstack, NULL); + stmt2->expr = create_objectnode(tempobj); + } else { + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt1); + stmt->expr = stmt2->expr; + stmt->sourceoffset = stmt2->sourceoffset; + stmt->sourcefilepath = stmt2->sourcefilepath; + DestructLocals(stmt, stmt2->dobjstack, NULL); + stmt2->expr = nullnode(); + } + } +} + +static Statement *DestructorIfTransform(Statement *stmt) { + CLabel *label; + Statement *newStmt; + + if (stmt->type == ST_IFGOTO) + stmt->type = ST_IFNGOTO; + else + stmt->type = ST_IFGOTO; + + label = newlabel(); + newStmt = DestructLocals(stmt, stmt->dobjstack, FindLastNonCommonStackObj(stmt, stmt->label->stmt)); + newStmt = CFunc_InsertStatement(ST_GOTO, newStmt); + newStmt->label = stmt->label; + newStmt = CFunc_InsertStatement(ST_LABEL, newStmt); + newStmt->label = label; + label->stmt = newStmt; + stmt->label = label; + newStmt->dobjstack = stmt->dobjstack; + return newStmt; +} + +static Boolean IsSubStack(ExceptionAction *exc1, ExceptionAction *exc2) { + if (!exc1) + return 1; + + while (exc2) { + if (exc2 == exc1) + return 1; + exc2 = exc2->prev; + } + + return 0; +} + +static void CFunc_CheckInitSkip(Statement *stmt, ExceptionAction *exc) { + if (stmt->dobjstack != exc && !IsSubStack(exc, stmt->dobjstack)) { + while (exc) { + if (CExcept_ActionNeedsDestruction(exc) && exc->type != EAT_ACTIVECATCHBLOCK) { + CError_Warning(CErrorStr211); + break; + } + exc = exc->prev; + } + } +} + +void CFunc_DestructorCleanup(Statement *stmt) { + Statement *scan; + Statement *next; + SwitchCase *swcase; + + if (copts.cplusplus) { + for (scan = stmt; scan; scan = scan->next) { + switch (scan->type) { + case ST_NOP: + case ST_LABEL: + case ST_EXPRESSION: + case ST_RETURN: + case ST_BEGINCATCH: + case ST_ENDCATCH: + case ST_ENDCATCHDTOR: + case ST_GOTOEXPR: + case ST_ASM: + break; + case ST_SWITCH: + CFunc_CheckInitSkip(scan, ((SwitchInfo *) scan->label)->defaultlabel->stmt->dobjstack); + for (swcase = ((SwitchInfo *) scan->label)->cases; swcase; swcase = swcase->next) { + CFunc_CheckInitSkip(scan, swcase->label->stmt->dobjstack); + } + break; + case ST_GOTO: + case ST_IFGOTO: + case ST_IFNGOTO: + CFunc_CheckInitSkip(scan, scan->label->stmt->dobjstack); + break; + default: + CError_FATAL(1045); + } + } + + if (cexcept_hasdobjects) { + while (1) { + next = stmt->next; + if (!next) { + if (stmt->type != ST_RETURN && stmt->dobjstack) + DestructLocals(stmt, stmt->dobjstack, NULL); + return; + } + + switch (next->type) { + case ST_GOTO: + if ( + stmt->dobjstack != next->label->stmt->dobjstack && + NeedsDestruction(stmt, next->label->stmt) + ) + { + DestructLocals(stmt, stmt->dobjstack, FindLastNonCommonStackObj(stmt, next->label->stmt)); + } + stmt = next; + continue; + + case ST_RETURN: + if (next->expr && DestructorNeeded(stmt->dobjstack, NULL)) { + DestructorReturnTransform(stmt, next); + } else if (stmt->dobjstack) { + DestructLocals(stmt, stmt->dobjstack, NULL); + } + stmt = next; + continue; + } + + switch (stmt->type) { + case ST_GOTO: + case ST_SWITCH: + case ST_RETURN: + case ST_GOTOEXPR: + break; + case ST_NOP: + case ST_LABEL: + case ST_EXPRESSION: + case ST_IFGOTO: + case ST_IFNGOTO: + case ST_BEGINCATCH: + case ST_ENDCATCH: + case ST_ENDCATCHDTOR: + case ST_ASM: + if ( + stmt->dobjstack != next->dobjstack && + NeedsDestruction(stmt, next) + ) + { + DestructLocals(stmt, stmt->dobjstack, FindLastNonCommonStackObj(stmt, next)); + } + break; + default: + CError_FATAL(1109); + } + + switch (next->type) { + case ST_NOP: + case ST_LABEL: + case ST_EXPRESSION: + case ST_SWITCH: + case ST_BEGINCATCH: + case ST_ENDCATCH: + case ST_ENDCATCHDTOR: + case ST_ASM: + stmt = next; + continue; + + case ST_IFGOTO: + case ST_IFNGOTO: + if ( + next->dobjstack != next->label->stmt->dobjstack && + NeedsDestruction(next, next->label->stmt) + ) + { + stmt = DestructorIfTransform(next); + } else { + stmt = next; + } + break; + + default: + CError_FATAL(1138); + } + } + } + } +} + +static void scancase(DeclThing *thing) { + SwitchCase *swcase; + Statement *stmt; + CInt64 min; + CInt64 max; + + if (!thing->switchinfo) { + CError_Error(CErrorStr169); + return; + } + + tk = lex(); + min = CExpr_IntConstConvert(thing->switchinfo->x8, thing->switchinfo->x8, CExpr_IntegralConstExpr()); + if (!copts.ANSI_strict && tk == TK_ELLIPSIS) { + tk = lex(); + max = CExpr_IntConstConvert(thing->switchinfo->x8, thing->switchinfo->x8, CExpr_IntegralConstExpr()); + if (CInt64_Greater(min, max)) + CError_Error(CErrorStr366); + if (thing->switchinfo->x8->size == stsignedlonglong.size) + CError_Error(CErrorStr368); + } else { + max = min; + } + + for (swcase = thing->switchinfo->cases; swcase; swcase = swcase->next) { + if (CInt64_GreaterEqual(swcase->min, min) && CInt64_LessEqual(swcase->min, max)) + CError_Error(CErrorStr172); + if (CInt64_GreaterEqual(swcase->max, min) && CInt64_LessEqual(swcase->max, max)) + CError_Error(CErrorStr172); + if (CInt64_Less(swcase->min, min) && CInt64_Greater(swcase->max, max)) + CError_Error(CErrorStr172); + } + + stmt = CFunc_AppendStatement(ST_LABEL); + stmt->label = newlabel(); + stmt->label->stmt = stmt; + + swcase = lalloc(sizeof(SwitchCase)); + swcase->min = min; + swcase->label = stmt->label; + swcase->next = thing->switchinfo->cases; + thing->switchinfo->cases = swcase; + swcase->max = max; + + if (tk != ':') + CError_ErrorSkip(CErrorStr170); + else + tk = lex(); + + statement(thing); +} + +static void CFunc_NameLocalStaticDataObject(Object *obj, char *str) { + char buf[64]; + HashNameNode *name; + + if (!(cscope_currentfunc && (cscope_currentfunc->qual & Q_INLINE)) || CParser_HasInternalLinkage(cscope_currentfunc)) { + obj->name = CParser_AppendUniqueName(str); + } else { + sprintf(buf, "$localstatic%ld$", cfunc_staticvarcount++); + name = CMangler_GetLinkName(cscope_currentfunc); + name = CParser_NameConcat(buf, name->name); + name = CParser_NameConcat(str, name->name); + obj->name = name; + obj->qual |= Q_20000; + obj->sclass = 0; + } +} + +static void sinit_insert_expr(ENode *expr) { + Statement *stmt; + + if (!sinit_first_object) { + sinit_first_object = CParser_NewCompilerDefDataObject(); + sinit_first_object->type = TYPE(&stsignedchar); + sinit_first_object->sclass = TK_STATIC; + CFunc_NameLocalStaticDataObject(sinit_first_object, "init"); + CInit_DeclareData(sinit_first_object, NULL, NULL, sinit_first_object->type->size); + + sinit_label = newlabel(); + stmt = CFunc_AppendStatement(ST_IFGOTO); + stmt->expr = create_objectnode(sinit_first_object); + stmt->label = sinit_label; + } + + stmt = CFunc_AppendStatement(ST_EXPRESSION); + stmt->expr = expr; +} + +static void ainit_insert_expr(ENode *expr) { + Statement *stmt; + + if (ainit_only_one) { + if (ainit_expr) { + stmt = CFunc_AppendStatement(ST_EXPRESSION); + stmt->expr = ainit_expr; + } + ainit_expr = expr; + } else { + stmt = CFunc_AppendStatement(ST_EXPRESSION); + stmt->expr = expr; + } +} + +static ENode *ainit_register_object(Type *type, Object *local, SInt32 offset, Boolean flag) { + return CExcept_RegisterDestructorObject(local, offset, CClass_Destructor(TYPE_CLASS(type)), flag); +} + +static void CFunc_LocalDataDeclarator(DeclInfo *di, TStreamElement *deftoken, Boolean flag1, Boolean flag2) { + Object *object; + Object *aliasObject; + NameSpace *globalNS; + NameSpaceObjectList *nsol; + NameSpaceName *nsname; + Statement *stmt; + + if (di->nspace) + CError_Error(CErrorStr121); + + CDecl_CompleteType(di->thetype); + + object = NULL; + + if ((nsol = CScope_FindName(cscope_current, di->name))) { + switch (nsol->object->otype) { + case OT_OBJECT: + object = OBJECT(nsol->object); + break; + case OT_NAMESPACE: + CError_Error(CErrorStr321); + return; + case OT_ENUMCONST: + case OT_TYPE: + CError_Error(CErrorStr322); + break; + case OT_TYPETAG: + break; + default: + CError_FATAL(1344); + } + } + + if (object) + CError_Error(CErrorStr333, object); + + if (di->storageclass == TK_EXTERN) { + object = NULL; + globalNS = CScope_FindGlobalNS(cscope_current); + if ((nsol = CScope_FindName(globalNS, di->name))) { + switch (nsol->object->otype) { + case OT_OBJECT: + object = OBJECT(nsol->object); + break; + case OT_NAMESPACE: + CError_Error(CErrorStr321); + return; + case OT_ENUMCONST: + case OT_TYPE: + CError_Error(CErrorStr322); + break; + case OT_TYPETAG: + break; + default: + CError_FATAL(1381); + } + } + + if (object) { + if ( + !is_typesame(di->thetype, object->type) || + (di->qual & (Q_CONST | Q_VOLATILE | Q_PASCAL | Q_20000 | Q_OVERLOAD | Q_ALIGNED_MASK)) != (object->qual & (Q_CONST | Q_VOLATILE | Q_PASCAL | Q_20000 | Q_OVERLOAD | Q_ALIGNED_MASK)) + ) + { + CError_Error(CErrorStr249, di->name->name, object->type, object->qual, di->thetype, di->qual); + } + } else { + object = CParser_NewGlobalDataObject(di); + object->nspace = globalNS; + } + + CParser_NewAliasObject(object, 0); + return; + } + + if (di->storageclass != TK_STATIC) + object = CParser_NewObject(di); + else + object = CParser_NewGlobalDataObject(di); + + object->name = di->name; + object->type = di->thetype; + object->qual = di->qual; + object->sclass = di->storageclass; + + switch (di->storageclass) { + case TK_STATIC: + if (flag1) { + CError_Error(CErrorStr177); + return; + } + if (flag2) + CError_Error(CErrorStr174); + + if (CanCreateObject(di->thetype)) { + CError_QualifierCheck(di->qual & ~(Q_CONST | Q_VOLATILE | Q_PASCAL | Q_20000 | Q_OVERLOAD | Q_ALIGNED_MASK)); + CParser_NewAliasObject(object, 0); + object->nspace = cscope_root; + object->datatype = DDATA; + CFunc_NameLocalStaticDataObject(object, object->name->name); + + if (copts.cplusplus) { + sinit_first_object = NULL; + CInit_InitializeStaticData(object, sinit_insert_expr); + if (sinit_first_object) { + stmt = CFunc_AppendStatement(ST_EXPRESSION); + stmt->expr = makediadicnode( + create_objectnode(sinit_first_object), + intconstnode(TYPE(&stsignedchar), 1), + EASS); + stmt = CFunc_AppendStatement(ST_LABEL); + stmt->label = sinit_label; + sinit_label->stmt = stmt; + } + } else { + CInit_InitializeData(object); + } + } + break; + + case 0: + case TK_AUTO: + case TK_REGISTER: + if (CanCreateObject(di->thetype)) { + CError_QualifierCheck(di->qual & ~(Q_CONST | Q_VOLATILE | Q_PASCAL | Q_ALIGNED_MASK)); + object->datatype = DLOCAL; + CFunc_SetupLocalVarInfo(object); + + object->u.var.info->deftoken = *deftoken; + if (object->sclass == TK_REGISTER && flag1) + object->u.var.info->usage = 100; + + CScope_AddObject(cscope_current, object->name, OBJ_BASE(object)); + + if (!flag1) { + if (IS_TYPE_SOM_CLASS(di->thetype)) { + CSOM_InitAutoClass(object); + } else { + CInit_InitializeAutoData(object, ainit_insert_expr, ainit_register_object); + if (object->type != di->thetype && (IS_TYPE_STRUCT(object->type) || IS_TYPE_CLASS(object->type))) { + CError_ASSERT(1478, !cscope_current->is_hash); + CError_ASSERT(1479, nsname = CScope_FindNameSpaceName(cscope_current, object->name)); + CError_ASSERT(1480, nsname->first.object == OBJ_BASE(object)); + CError_ASSERT(1481, !nsname->first.next); + nsname->name = CParser_AppendUniqueName(object->name->name); + + aliasObject = CParser_NewAliasObject(object, 0); + aliasObject->type = di->thetype; + } + } + } + + if (object->datatype == DLOCAL) { + ObjectList *list = lalloc(sizeof(ObjectList)); + list->object = object; + list->next = locals; + locals = list; + } + + IsCompleteType(di->thetype); + } + break; + + default: + CError_FATAL(1504); + } +} + +static ENode *CFunc_ParseLocalDeclarationList(Boolean flag1, Boolean flag2, Boolean flag3, Boolean flag4) { + Type *type; + UInt32 qual; + DeclInfo di; + TStreamElement deftoken; + + ainit_expr = NULL; + ainit_only_one = flag2; + + while (flag2 || isdeclaration(copts.cplusplus, 0, 0, 0)) { + CPrep_GetFileOffsetInfo2(&cparser_fileoffset, &sourceoffset, &sourcefilepath); + + memclrw(&di, sizeof(di)); + di.x4E = cfunc_is_extern_c; + CParser_GetDeclSpecs(&di, 0); + + if (IS_TYPE_TEMPLATE(di.thetype)) { + CError_Error(CErrorStr146); + di.thetype = TYPE(&stsignedint); + } + + type = di.thetype; + qual = di.qual; + + if (tk != ';') { + while (1) { + deftoken = *CPrep_CurStreamElement(); + di.name = NULL; + scandeclarator(&di); + + if (di.name) { + if (di.storageclass != TK_TYPEDEF) { + if (IS_TYPE_FUNC(di.thetype)) { + if (!CDecl_FunctionDeclarator(&di, CScope_FindGlobalNS(cscope_current), 0, 0)) + break; + } else { + CFunc_LocalDataDeclarator(&di, &deftoken, flag1, flag2); + } + } else { + CDecl_TypedefDeclarator(&di); + } + } else { + CError_Error(CErrorStr134); + } + + if (tk == ';') + break; + + if (tk != ',') { + if (!flag2) + CError_Error(CErrorStr123); + break; + } + + di.nspace = NULL; + di.thetype = type; + di.qual = qual; + tk = lex(); + } + } else { + CParser_CheckAnonymousUnion(&di, 1); + } + + if (flag2) + break; + if (flag4) + break; + tk = lex(); + } + + if (flag2) { + if (!ainit_expr) { + if (!flag3) { + CError_Error(CErrorStr141); + ainit_expr = nullnode(); + } + } else { + ainit_expr = checkreference(ainit_expr); + } + } + + return ainit_expr; +} + +static void makeifstatement(ENode *expr, CLabel *label1, CLabel *label2, Boolean flag1, Boolean flag2) { + Statement *stmt; + CLabel *tmplabel; + + if (!expr) { + if (flag1) { + stmt = CFunc_AppendStatement(ST_GOTO); + stmt->label = label1; + return; + } + return; + } + + if ( + ENODE_IS(expr, ETYPCON) && + IS_TYPE_INT(expr->rtype) && + IS_TYPE_INT(expr->data.monadic->rtype) && + expr->rtype->size >= expr->data.monadic->rtype->size + ) + expr = expr->data.monadic; + + if (isnotzero(expr)) { + if (flag1) { + stmt = CFunc_AppendStatement(ST_GOTO); + stmt->label = label1; + return; + } + return; + } + + if (iszero(expr)) { + if (!flag1) { + stmt = CFunc_AppendStatement(ST_GOTO); + stmt->label = label1; + return; + } + return; + } + + if (ENODE_IS(expr, ELOGNOT)) { + makeifstatement(expr->data.monadic, label1, label2, !flag1, flag2); + return; + } + + if (ENODE_IS(expr, ELOR)) { + tmplabel = newlabel(); + if (flag1) { + makeifstatement(expr->data.diadic.left, label1, tmplabel, 1, flag2); + tmplabel->stmt = CFunc_AppendStatement(ST_LABEL); + tmplabel->stmt->label = tmplabel; + makeifstatement(expr->data.diadic.right, label1, label2, 1, flag2); + return; + } else { + makeifstatement(expr->data.diadic.left, label2, tmplabel, 1, flag2); + tmplabel->stmt = CFunc_AppendStatement(ST_LABEL); + tmplabel->stmt->label = tmplabel; + makeifstatement(expr->data.diadic.right, label1, label2, 0, flag2); + return; + } + } + + if (ENODE_IS(expr, ELAND)) { + tmplabel = newlabel(); + if (flag1) { + makeifstatement(expr->data.diadic.left, label2, tmplabel, 0, flag2); + tmplabel->stmt = CFunc_AppendStatement(ST_LABEL); + tmplabel->stmt->label = tmplabel; + makeifstatement(expr->data.diadic.right, label1, label2, 1, flag2); + return; + } else { + makeifstatement(expr->data.diadic.left, label1, tmplabel, 0, flag2); + tmplabel->stmt = CFunc_AppendStatement(ST_LABEL); + tmplabel->stmt->label = tmplabel; + makeifstatement(expr->data.diadic.right, label1, label2, 0, flag2); + return; + } + } + + stmt = CFunc_AppendStatement(ST_IFGOTO); + stmt->label = label1; + stmt->expr = expr; + if (!flag1) + stmt->type = ST_IFNGOTO; + if (flag2) + stmt->flags |= StmtFlag_4; +} + +static void CFunc_HasDtorTempCallBack(ENode *expr) { + if (expr->data.temp.needs_dtor || expr->data.temp.uniqueid) + cfunc_hasdtortemp = 1; +} + +static void ifstatement(Boolean flag1, ENode *expr, CLabel *label, Boolean flag2) { + Statement *stmt; + CLabel *tmplabel; + + if (expr && copts.cplusplus && copts.exceptions) { + cfunc_hasdtortemp = 0; + CExpr_SearchExprTree(expr, CFunc_HasDtorTempCallBack, 1, ETEMP); + if (cfunc_hasdtortemp) { + stmt = CFunc_AppendStatement(flag1 ? ST_IFGOTO : ST_IFNGOTO); + stmt->label = label; + stmt->expr = expr; + if (flag2) + stmt->flags |= StmtFlag_4; + return; + } + } + + tmplabel = newlabel(); + makeifstatement(expr, label, tmplabel, flag1, flag2); + tmplabel->stmt = CFunc_AppendStatement(ST_LABEL); + tmplabel->stmt->label = tmplabel; +} + +Statement *CFunc_GenerateLoop(Statement *stmt, Type *type, ENode *lowerBound, ENode *upperBound, ENode *increment1, ENode *increment2, ENode *(*callback)(ENode *, ENode *)) { + ENode *var1; + ENode *var2; + CLabel *label; + ENode *ind; + ENode *ind2; + Statement *s; + + var1 = CExpr_NewETEMPNode(type, 1); + ind = lalloc(sizeof(ENode)); + *ind = *var1; + ind = makemonadicnode(ind, EINDIRECT); + ind->rtype = type; + + // initialise var1 to lowerBound + if (stmt) { + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + s = stmt; + } else { + s = CFunc_AppendStatement(ST_EXPRESSION); + } + s->expr = makediadicnode(ind, lowerBound, EASS); + + if (increment2) { + var2 = CExpr_NewETEMPNode(type, 1); + ind = lalloc(sizeof(ENode)); + *ind = *var2; + ind = makemonadicnode(ind, EINDIRECT); + ind->rtype = type; + + // initialise var2 to upperBound + if (stmt) { + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + s = stmt; + } else { + s = CFunc_AppendStatement(ST_EXPRESSION); + } + s->expr = makediadicnode(ind, upperBound, EASS); + } + + // label for loop body + label = newlabel(); + if (stmt) { + stmt = CFunc_InsertStatement(ST_LABEL, stmt); + s = stmt; + } else { + s = CFunc_AppendStatement(ST_LABEL); + } + s->label = label; + label->stmt = s; + + if (callback) { + ind = lalloc(sizeof(ENode)); + *ind = *var1; + ind = makemonadicnode(ind, EINDIRECT); + ind->rtype = type; + + if (increment2) { + ind2 = lalloc(sizeof(ENode)); + *ind2 = *var2; + ind2 = makemonadicnode(ind2, EINDIRECT); + ind2->rtype = type; + } else { + ind2 = NULL; + } + + // generate a loop body + if ((ind = callback(ind, ind2))) { + if (stmt) { + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + s = stmt; + } else { + s = CFunc_AppendStatement(ST_EXPRESSION); + } + s->expr = ind; + } + } + + if (increment1) { + ind = lalloc(sizeof(ENode)); + *ind = *var1; + ind = makemonadicnode(ind, EINDIRECT); + ind->rtype = type; + + // add increment1 to var1 + if (stmt) { + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + s = stmt; + } else { + s = CFunc_AppendStatement(ST_EXPRESSION); + } + s->expr = makediadicnode(ind, increment1, EADDASS); + + if (increment2) { + ind = lalloc(sizeof(ENode)); + *ind = *var2; + ind = makemonadicnode(ind, EINDIRECT); + ind->rtype = type; + + // add increment2 to var2 + if (stmt) { + stmt = CFunc_InsertStatement(ST_EXPRESSION, stmt); + s = stmt; + } else { + s = CFunc_AppendStatement(ST_EXPRESSION); + } + s->expr = makediadicnode(ind, increment2, EADDASS); + } + } + + ind = lalloc(sizeof(ENode)); + *ind = *var1; + ind = makemonadicnode(ind, EINDIRECT); + ind->rtype = type; + + // loop if var1 < upperBound + if (stmt) { + stmt = CFunc_InsertStatement(ST_IFGOTO, stmt); + s = stmt; + } else { + s = CFunc_AppendStatement(ST_IFGOTO); + } + s->expr = makediadicnode(ind, upperBound, ELESS); + s->expr->rtype = TYPE(&stbool); + s->label = label; + s->flags = StmtFlag_4; + + return stmt; +} + +static Boolean checklabel(void) { + HashNameNode *savename; + short savesize; + short token; + + savename = tkidentifier; + savesize = tksize; + token = lookahead(); + tkidentifier = savename; + tksize = savesize; + + return token == ':'; +} + +static ENode *returnstatementadjust(ENode *expr, Type *type, UInt32 qual) { + Object *object; + ENode *expr2; + ENode *objexpr; + ObjectList *list; + ENodeList *exprlist; + + for (list = arguments; list; list = list->next) { + if (list->object->name == temp_argument_name) + break; + } + + CError_ASSERT(1907, list); + + object = list->object; + if ((expr2 = CExpr_IsTempConstruction(expr, type, &objexpr)) && ENODE_IS(objexpr, ETEMP)) { + *objexpr = *create_objectnode(object); + return expr2; + } + + if (IS_TYPE_CLASS(type)) { + expr2 = create_objectnode(object); + exprlist = lalloc(sizeof(ENodeList)); + exprlist->next = NULL; + exprlist->node = expr; + return CExpr_ConstructObject(TYPE_CLASS(type), expr2, exprlist, 1, 1, 0, 1, 0); + } + + expr2 = create_objectnode(object); + expr2 = makemonadicnode(expr2, EINDIRECT); + expr2->rtype = type; + + return makediadicnode(expr2, CExpr_AssignmentPromotion(expr, type, qual, 1), EASS); +} + +static void CFunc_AutoResultCheck(ENode *expr) { + while (1) { + while (ENODE_IS(expr, ECOMMA)) + expr = expr->data.diadic.right; + + switch (expr->type) { + case EOBJREF: + if (expr->data.objref->datatype != DLOCAL) + break; + case ETEMP: + CError_Warning(CErrorStr326); + break; + case EADD: + case ESUB: + CFunc_AutoResultCheck(expr->data.diadic.left); + expr = expr->data.diadic.right; + continue; + default: + break; + } + break; + } +} + +static void statement(DeclThing *thing) { + Statement *stmt; + Statement *stmt2; + CLabel *label; + DeclBlock *block; + ENode *expr; + HashNameNode *name; + DeclThing subthing; + + CPrep_GetFileOffsetInfo2(&cparser_fileoffset, &sourceoffset, &sourcefilepath); + + switch (tk) { + case TK_RETURN: + tk = lex(); + if ( + (thing->thetype == &stvoid && !copts.cplusplus) || + CClass_IsConstructor(cscope_currentfunc) || + CClass_IsDestructor(cscope_currentfunc) + ) + { + if (tk != ';') { + CError_Error(CErrorStr315); + expression(); + } + + stmt = CFunc_AppendStatement(ST_RETURN); + stmt->expr = NULL; + CError_ResetErrorSkip(); + tk = lex(); + return; + } + + if (tk == ';') { + if (thing->thetype != &stvoid && (copts.pedantic || copts.cplusplus)) + CError_Warning(CErrorStr184); + + stmt = CFunc_AppendStatement(ST_RETURN); + stmt->expr = NULL; + CError_ResetErrorSkip(); + tk = lex(); + return; + } + + if (copts.old_argmatch) + expr = expression(); + else + expr = s_expression(); + + if (thing->thetype == &stvoid) { + if (expr->rtype != &stvoid) + CError_Error(CErrorStr315); + + stmt = CFunc_AppendStatement(ST_EXPRESSION); + stmt->expr = expr; + + stmt = CFunc_AppendStatement(ST_RETURN); + stmt->expr = NULL; + } else { + if (CMach_GetFunctionResultClass(TYPE_FUNC(cscope_currentfunc->type)) == 1) + expr = returnstatementadjust(expr, thing->thetype, thing->qual); + else + expr = CExpr_AssignmentPromotion(expr, thing->thetype, thing->qual, 1); + + stmt = CFunc_AppendStatement(ST_RETURN); + stmt->expr = expr; + + if (IS_TYPE_POINTER_ONLY(thing->thetype)) + CFunc_AutoResultCheck(expr); + } + + break; + + case TK_CASE: + scancase(thing); + return; + + case TK_DEFAULT: + if (!thing->switchinfo) { + CError_Error(CErrorStr169); + return; + } + + if (lex() != ':') + CError_ErrorSkip(CErrorStr170); + else + tk = lex(); + + if (thing->switchinfo->defaultlabel) + CError_ErrorSkip(CErrorStr173); + + stmt = CFunc_AppendStatement(ST_LABEL); + stmt->label = newlabel(); + stmt->label->stmt = stmt; + thing->switchinfo->defaultlabel = stmt->label; + statement(thing); + return; + + case TK_SWITCH: + if (lex() != '(') + CError_ErrorSkip(CErrorStr114); + else + tk = lex(); + + if (copts.cplusplus && !copts.ARM_scoping && isdeclaration(1, 0, 0, '=')) { + block = CFunc_NewDeclBlock(); + expr = CFunc_ParseLocalDeclarationList(0, 1, 0, 0); + if (CScope_IsEmptyNameSpace(cscope_current)) { + CFunc_RestoreBlock(block); + block = NULL; + } + } else { + expr = expression(); + block = NULL; + } + + stmt = CFunc_AppendStatement(ST_SWITCH); + stmt->expr = CExpr_ConvertToIntegral(expr); + + if (tk != ')') + CError_ErrorSkip(CErrorStr115); + else + tk = lex(); + + stmt->label = (CLabel *) lalloc(sizeof(SwitchInfo)); + ((SwitchInfo *) stmt->label)->defaultlabel = NULL; + ((SwitchInfo *) stmt->label)->cases = NULL; + ((SwitchInfo *) stmt->label)->x8 = stmt->expr->rtype; + + label = newlabel(); + subthing = *thing; + subthing.loopBreak = label; + subthing.switchinfo = (SwitchInfo *) stmt->label; + CFunc_CompoundStatement(&subthing); + + if (!subthing.switchinfo->defaultlabel) + subthing.switchinfo->defaultlabel = label; + + if (!subthing.switchinfo->cases) { + stmt->type = ST_EXPRESSION; + stmt2 = lalloc(sizeof(Statement)); + *stmt2 = *stmt; + stmt->next = stmt2; + stmt2->type = ST_GOTO; + stmt2->label = subthing.switchinfo->defaultlabel; + stmt2->dobjstack = cexcept_dobjstack; + } + + stmt = CFunc_AppendStatement(ST_LABEL); + stmt->label = label; + label->stmt = stmt; + + if (block) + CFunc_RestoreBlock(block); + return; + + case TK_GOTO: + if ((tk = lex()) != TK_IDENTIFIER) { + if (tk == '*' && !copts.ANSI_strict) { + tk = lex(); + stmt = CFunc_AppendStatement(ST_GOTOEXPR); + stmt->expr = expression(); + if (!IS_TYPE_POINTER_ONLY(stmt->expr->rtype)) { + CError_Error(CErrorStr146); + stmt->expr = nullnode(); + stmt->expr->rtype = TYPE(&void_ptr); + } + } else { + CError_Error(CErrorStr107); + return; + } + } else { + stmt = CFunc_AppendStatement(ST_GOTO); + if (!(stmt->label = findlabel())) { + stmt->label = newlabel(); + stmt->label->next = Labels; + Labels = stmt->label; + stmt->label->name = tkidentifier; + } + tk = lex(); + } + break; + + case TK_BREAK: + if (thing->loopBreak) { + stmt = CFunc_AppendStatement(ST_GOTO); + stmt->label = thing->loopBreak; + } else { + CError_Error(CErrorStr169); + } + tk = lex(); + break; + + case TK_CONTINUE: + if (thing->loopContinue) { + stmt = CFunc_AppendStatement(ST_GOTO); + stmt->label = thing->loopContinue; + } else { + CError_Error(CErrorStr169); + } + tk = lex(); + break; + + case TK_FOR: { + CLabel *forLabel1; + CLabel *forLabel2; + CLabel *forLabel3; + ENode *forCond; + ENode *forInc; + + if (lex() != '(') + CError_ErrorSkip(CErrorStr114); + else + tk = lex(); + + block = NULL; + if (tk != ';') { + if (!copts.cplusplus || !isdeclaration(1, 0, 0, 0)) { + expr = expression(); + CExpr_CheckUnusedExpression(expr); + } else { + if (!copts.ARM_scoping) + block = CFunc_NewDeclBlock(); + expr = CFunc_ParseLocalDeclarationList(0, 1, 1, 0); + if (block && CScope_IsEmptyNameSpace(cscope_current)) { + CFunc_RestoreBlock(block); + block = NULL; + } + } + + if (expr) { + stmt = CFunc_AppendStatement(ST_EXPRESSION); + stmt->expr = expr; + } + + if (tk == ';') + CError_ResetErrorSkip(); + else + CError_Error(CErrorStr123); + } else { + CError_ResetErrorSkip(); + } + + if ((tk = lex()) != ';') { + if (copts.cplusplus && !copts.ARM_scoping && isdeclaration(1, 0, 0, '=')) { + if (!block) + block = CFunc_NewDeclBlock(); + expr = CFunc_ParseLocalDeclarationList(0, 1, 0, 0); + if (CScope_IsEmptyNameSpace(cscope_current)) { + CFunc_RestoreBlock(block); + block = NULL; + } + } else { + expr = expression(); + CExpr_CheckUnwantedAssignment(expr); + } + + forCond = CExpr_ConvertToCondition(expr); + + if (tk == ';') + CError_ResetErrorSkip(); + else + CError_Error(CErrorStr123); + } else { + CError_ResetErrorSkip(); + forCond = NULL; + } + + if ((tk = lex()) != ')') { + forInc = expression(); + CExpr_CheckUnusedExpression(forInc); + if (tk == ')') + CError_ResetErrorSkip(); + else + CError_Error(CErrorStr115); + } else { + CError_ResetErrorSkip(); + forInc = NULL; + } + + if (copts.warn_possunwant) { + spaceskip = 0; + if ((tk = lex()) == ';' && !spaceskip) + CError_Warning(CErrorStr206); + } else { + tk = lex(); + } + + if (forCond) { + stmt = CFunc_AppendStatement(ST_GOTO); + label = newlabel(); + stmt->label = label; + } else { + label = newlabel(); + } + + CFunc_LoopIncrement(); + + stmt = CFunc_AppendStatement(ST_LABEL); + forLabel1 = stmt->label = newlabel(); + forLabel1->stmt = stmt; + + forLabel2 = newlabel(); + forLabel3 = newlabel(); + + subthing = *thing; + subthing.loopContinue = forLabel3; + subthing.loopBreak = forLabel2; + + if (tk != '{') { + DeclBlock *b = CFunc_NewDeclBlock(); + CFunc_CompoundStatement(&subthing); + CFunc_RestoreBlock(b); + } else { + CFunc_CompoundStatement(&subthing); + } + + stmt = CFunc_AppendStatement(ST_LABEL); + stmt->label = forLabel3; + forLabel3->stmt = stmt; + + if (forInc) { + stmt = CFunc_AppendStatement(ST_EXPRESSION); + stmt->expr = forInc; + } + + stmt = CFunc_AppendStatement(ST_LABEL); + stmt->label = label; + label->stmt = stmt; + + ifstatement(1, forCond, forLabel1, 1); + CFunc_LoopDecrement(); + + stmt = CFunc_AppendStatement(ST_LABEL); + stmt->label = forLabel2; + forLabel2->stmt = stmt; + + if (block) + CFunc_RestoreBlock(block); + + return; + } + + case TK_DO: { + CLabel *label1; + CLabel *label2; + CLabel *label3; + + CFunc_LoopIncrement(); + stmt = CFunc_AppendStatement(ST_LABEL); + label1 = stmt->label = newlabel(); + label1->stmt = stmt; + + label2 = newlabel(); + label3 = newlabel(); + + subthing = *thing; + subthing.loopContinue = label2; + subthing.loopBreak = label3; + + tk = lex(); + CFunc_CompoundStatement(&subthing); + + stmt = CFunc_AppendStatement(ST_LABEL); + stmt->label = label2; + label2->stmt = stmt; + + if (tk != TK_WHILE) + CError_Error(CErrorStr105); + + if (lex() != '(') + CError_ErrorSkip(CErrorStr114); + else + tk = lex(); + + expr = CExpr_ConvertToCondition(expression()); + CExpr_CheckUnwantedAssignment(expr); + + if (tk != ')') + CError_ErrorSkip(CErrorStr115); + else + tk = lex(); + + ifstatement(1, expr, label1, 1); + + CFunc_LoopDecrement(); + + stmt = CFunc_AppendStatement(ST_LABEL); + stmt->label = label3; + label3->stmt = stmt; + break; + } + + case TK_WHILE: { + CLabel *label1; + CLabel *label2; + CLabel *label3; + + if ((tk = lex()) != '(') + CError_ErrorSkip(CErrorStr114); + else + tk = lex(); + + if (copts.cplusplus && !copts.ARM_scoping && isdeclaration(1, 0, 0, '=')) { + block = CFunc_NewDeclBlock(); + expr = CFunc_ParseLocalDeclarationList(0, 1, 0, 0); + if (CScope_IsEmptyNameSpace(cscope_current)) { + CFunc_RestoreBlock(block); + block = NULL; + } + } else { + expr = expression(); + block = NULL; + CExpr_CheckUnwantedAssignment(expr); + } + expr = CExpr_ConvertToCondition(expr); + + if (tk != ')') { + CError_ErrorSkip(CErrorStr115); + } else { + if (copts.warn_possunwant) { + spaceskip = 0; + if ((tk = lex()) == ';' && !spaceskip) + CError_Warning(CErrorStr206); + } else { + tk = lex(); + } + } + + stmt = CFunc_AppendStatement(ST_GOTO); + label1 = newlabel(); + stmt->label = label1; + + CFunc_LoopIncrement(); + + stmt = CFunc_AppendStatement(ST_LABEL); + label2 = stmt->label = newlabel(); + label2->stmt = stmt; + + label3 = newlabel(); + + subthing = *thing; + subthing.loopContinue = label1; + subthing.loopBreak = label3; + + CFunc_CompoundStatement(&subthing); + + stmt = CFunc_AppendStatement(ST_LABEL); + stmt->label = label1; + label1->stmt = stmt; + + ifstatement(1, expr, label2, 1); + + CFunc_LoopDecrement(); + + stmt = CFunc_AppendStatement(ST_LABEL); + stmt->label = label3; + label3->stmt = stmt; + + if (block) + CFunc_RestoreBlock(block); + return; + } + + case TK_IF: { + CLabel *label1; + if ((tk = lex()) != '(') + CError_ErrorSkip(CErrorStr114); + else + tk = lex(); + + if (copts.cplusplus && !copts.ARM_scoping && isdeclaration(1, 0, 0, '=')) { + block = CFunc_NewDeclBlock(); + expr = CFunc_ParseLocalDeclarationList(0, 1, 0, 0); + if (CScope_IsEmptyNameSpace(cscope_current)) { + CFunc_RestoreBlock(block); + block = NULL; + } + } else { + expr = expression(); + block = NULL; + CExpr_CheckUnwantedAssignment(expr); + } + + expr = CExpr_ConvertToCondition(expr); + + label1 = newlabel(); + ifstatement(0, expr, label1, 0); + + if (tk != ')') { + CError_ErrorSkip(CErrorStr115); + } else { + if (copts.warn_possunwant) { + spaceskip = 0; + if ((tk = lex()) == ';' && !spaceskip) + CError_Warning(CErrorStr206); + } else { + tk = lex(); + } + } + + CFunc_CompoundStatement(thing); + + if (tk == TK_ELSE) { + if (copts.warn_possunwant) { + spaceskip = 0; + if ((tk = lex()) == ';' && !spaceskip) + CError_Warning(CErrorStr206); + } else { + tk = lex(); + } + + stmt = CFunc_AppendStatement(ST_GOTO); + label = stmt->label = newlabel(); + + stmt = CFunc_AppendStatement(ST_LABEL); + stmt->label = label1; + label1->stmt = stmt; + + CFunc_CompoundStatement(thing); + + label1 = label; + } + + stmt = CFunc_AppendStatement(ST_LABEL); + stmt->label = label1; + label1->stmt = stmt; + + if (block) + CFunc_RestoreBlock(block); + + return; + } + + case '{': + CFunc_CompoundStatement(thing); + return; + + case TK_ASM: + if (copts.cplusplus || !copts.ANSI_strict) { + tk = lex(); + volatileasm = 0; + + if (tk == TK_VOLATILE || (tk == TK_IDENTIFIER && !strcmp(tkidentifier->name, "__volatile__"))) { + tk = lex(); + volatileasm = 1; + } + + if (tk == '(') { + InlineAsm_Assemble(); + if (tk == ')') { + tk = lex(); + break; + } else { + CError_Error(CErrorStr115); + return; + } + } + + if (tk == '{') { + InlineAsm_Assemble(); + if (tk != '}') { + CError_Error(CErrorStr130); + return; + } + if ((tk = lex()) == ';') + tk = lex(); + CError_ResetErrorSkip(); + return; + } + + CError_Error(CErrorStr114); + } else { + CError_Error(CErrorStr121); + } + return; + + case TK_TRY: + tk = lex(); + CExcept_ScanTryBlock(thing, 0); + return; + + case TK_USING: + if ((tk = lex()) == TK_NAMESPACE) { + tk = lex(); + CScope_ParseUsingDirective(cscope_current); + } else { + CScope_ParseUsingDeclaration(cscope_current, 0, 0); + } + return; + + case TK_NAMESPACE: + if ((tk = lex()) != TK_IDENTIFIER) { + CError_Error(CErrorStr107); + return; + } + name = tkidentifier; + if ((tk = lex()) != '=') { + CError_Error(CErrorStr121); + return; + } + + CScope_ParseNameSpaceAlias(name); + break; + + case ';': + break; + + case TK_IDENTIFIER: + if (checklabel()) { + stmt = CFunc_AppendStatement(ST_LABEL); + if ((stmt->label = findlabel())) { + if (stmt->label->stmt) + CError_Error(CErrorStr171, tkidentifier->name); + } else { + stmt->label = newlabel(); + stmt->label->next = Labels; + Labels = stmt->label; + stmt->label->name = tkidentifier; + } + + stmt->label->stmt = stmt; + tk = lex(); + tk = lex(); + statement(thing); + return; + } + tk = TK_IDENTIFIER; + + default: + if (copts.cplusplus && isdeclaration(1, 0, 0, 0)) { + CFunc_ParseLocalDeclarationList(0, 0, 0, 1); + tk = lex(); + return; + } + + stmt = CFunc_AppendStatement(ST_EXPRESSION); + stmt->expr = expression(); + CExpr_CheckUnusedExpression(stmt->expr); + } + + if (tk == ';') { + CPrep_TokenStreamFlush(); + tk = lex(); + CError_ResetErrorSkip(); + } else { + CError_ErrorSkip(CErrorStr123); + } +} + +void CFunc_CompoundStatement(DeclThing *thing) { + DeclBlock *block; + + block = CFunc_NewDeclBlock(); + + if (tk == '{') { + tk = lex(); + if (!copts.cplusplus && isdeclaration(0, 0, 0, 0)) + CFunc_ParseLocalDeclarationList(0, 0, 0, 0); + + while (tk != '}') + statement(thing); + + CPrep_GetFileOffsetInfo2(&cparser_fileoffset, &sourceoffset, &sourcefilepath); + tk = lex(); + } else { + statement(thing); + } + + CFunc_RestoreBlock(block); +} + +static void CFunc_InsertArgumentCopyConversion(Object *obj, Type *type1, Type *type2, Boolean flag) { + Object *newobj; + Statement *stmt; + ENode *expr; + NameSpaceObjectList *nsol; + ObjectList *list; + + newobj = lalloc(sizeof(Object)); + *newobj = *obj; + newobj->type = type2; + + CFunc_SetupLocalVarInfo(newobj); + + obj->name = CParser_GetUniqueName(); + if (flag) + obj->type = CDecl_NewPointerType(type1); + else + obj->type = type1; + + CError_ASSERT(2527, (nsol = CScope_FindName(cscope_current, newobj->name)) && nsol->object == OBJ_BASE(obj)); + nsol->object = OBJ_BASE(newobj); + + list = lalloc(sizeof(ObjectList)); + list->object = newobj; + list->next = locals; + locals = list; + + stmt = CFunc_AppendStatement(ST_EXPRESSION); + expr = create_objectnode(obj); + if (flag) { + expr->rtype = CDecl_NewPointerType(type1); + expr = makemonadicnode(expr, EINDIRECT); + } + expr->rtype = type1; + + if (type1 != type2) + expr = promote(expr, type2); + + stmt->expr = makediadicnode(create_objectnode(newobj), expr, EASS); +} + +static void CFunc_AdjustOldStyleArgs(void) { + ObjectList *list; + + for (list = arguments; list; list = list->next) { + if (IS_TYPE_FLOAT(list->object->type) && list->object->type->size < stdouble.size) + CFunc_InsertArgumentCopyConversion(list->object, TYPE(&stdouble), list->object->type, 0); + } +} + +void CFunc_SetupNewFuncArgs(Object *func, FuncArg *args) { + Object *obj; + ObjectList *newlist; + + arguments = NULL; + + if (args != &elipsis && args != &oldstyle) { + newlist = NULL; + + while (args && args != &elipsis) { + IsCompleteType(args->type); + + obj = CParser_NewLocalDataObject(NULL, 0); + obj->name = !args->name ? no_name_node : args->name; + obj->type = args->type; + obj->qual = args->qual; + obj->sclass = args->sclass; + + CFunc_SetupLocalVarInfo(obj); + + if (IS_TYPE_CLASS(obj->type) && CClass_ReferenceArgument(TYPE_CLASS(obj->type))) { + obj->type = CDecl_NewPointerType(obj->type); + TPTR_QUAL(obj->type) = Q_REFERENCE | Q_RESTRICT; + } + + if (obj->name == no_name_node && copts.ANSI_strict && !copts.cplusplus && !(func->qual & Q_80000)) + CError_Error(CErrorStr127); + + if (newlist) { + newlist->next = lalloc(sizeof(ObjectList)); + newlist = newlist->next; + } else { + newlist = lalloc(sizeof(ObjectList)); + arguments = newlist; + } + + newlist->next = NULL; + newlist->object = obj; + + args = args->next; + } + } +} + +static ObjectList *CFunc_CopyObjectList(const FuncArg *args) { + Object *obj; + ObjectList *list; + ObjectList *last; + + list = NULL; + + while (args) { + if (list) { + last->next = lalloc(sizeof(ObjectList)); + last = last->next; + } else { + last = lalloc(sizeof(ObjectList)); + list = last; + } + + obj = CParser_NewLocalDataObject(NULL, 0); + obj->name = args->name; + obj->type = args->type; + obj->qual = args->qual; + obj->sclass = args->sclass; + CFunc_SetupLocalVarInfo(obj); + + last->object = obj; + last->next = NULL; + + args = args->next; + } + + return list; +} + +static void SetupFunctionArguments(Object *func, DeclInfo *di, Statement *firstStmt) { + ObjectList *list; + Object *resultobj; + Object *obj; + Type *type; + DeclInfo my_di; + + if (TYPE_FUNC(func->type)->args) { + if (di->x45) { + arguments = CFunc_CopyObjectList(di->x18); + while (1) { + if (tk == '{') + break; + + memclrw(&my_di, sizeof(my_di)); + CParser_GetDeclSpecs(&my_di, 0); + + type = my_di.thetype; + if (my_di.storageclass && my_di.storageclass != TK_REGISTER) + CError_Error(CErrorStr127); + + while (1) { + my_di.thetype = type; + my_di.name = NULL; + scandeclarator(&my_di); + if (!my_di.name) { + CError_Error(CErrorStr107); + break; + } + + adjustargumenttype(&my_di); + IsCompleteType(my_di.thetype); + + if ((obj = CFunc_IsInObjList(arguments, my_di.name))) { + if (obj->type) + CError_Error(CErrorStr333, obj); + obj->type = my_di.thetype; + obj->sclass = my_di.storageclass; + obj->qual = my_di.qual; + } else { + CError_Error(CErrorStr127); + } + + if (tk != ',') + break; + tk = lex(); + } + + if (tk != ';') + CError_ErrorSkip(CErrorStr123); + else + tk = lex(); + } + + for (list = arguments; list; list = list->next) { + if (!list->object->type) + list->object->type = TYPE(&stsignedint); + } + } else { + CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args); + } + } + + if (CMach_GetFunctionResultClass(TYPE_FUNC(func->type)) == 1) { + resultobj = CParser_NewLocalDataObject(NULL, 0); + resultobj->name = temp_argument_name; + resultobj->type = CDecl_NewPointerType(TYPE_FUNC(func->type)->functype); + CFunc_SetupLocalVarInfo(resultobj); + + list = lalloc(sizeof(ObjectList)); + list->object = resultobj; + if (CABI_GetStructResultArgumentIndex(TYPE_FUNC(func->type))) { + CError_ASSERT(2797, arguments); + list->next = arguments->next; + arguments->next = list; + } else { + list->next = arguments; + arguments = list; + } + } + + for (list = arguments; list; list = list->next) { + NameSpaceObjectList *nsol = CScope_InsertName(cscope_current, list->object->name); + nsol->object = OBJ_BASE(list->object); + } +} + +NameSpace *CFunc_FuncGenSetup(Statement *stmt, Object *func) { + NameSpace *nspace; + DeclBlock *block; + + nspace = CScope_NewListNameSpace(NULL, 0); + nspace->parent = cscope_current; + cscope_current = nspace; + + arguments = NULL; + locals = NULL; + Labels = NULL; + + localcount = 0; + cfunc_staticvarcount = 0; + + CExcept_Setup(); + + memclrw(stmt, sizeof(Statement)); + curstmt = stmt; + stmt->type = ST_NOP; + curstmtvalue = 1; + stmt->value = 1; + + blockcount = 0; + block = lalloc(sizeof(DeclBlock)); + memclrw(block, sizeof(DeclBlock)); + block->index = blockcount++; + block->parent_nspace = cscope_current; + + firstblock = block; + currentblock = block; + + return nspace; +} + +CFuncSave *CFunc_GetGlobalCompilerState(void) { + CFuncSave *state; + + if (!cscope_currentfunc && !cscope_currentclass && cscope_current == cscope_root) + return NULL; + + locklheap(); + state = lalloc(sizeof(CFuncSave)); + + CScope_SetNameSpaceScope(cscope_root, &state->scope); + + state->arguments = arguments; + arguments = NULL; + + state->locals = locals; + locals = NULL; + + state->labels = Labels; + Labels = NULL; + + state->curstmt = curstmt; + curstmt = NULL; + + state->firstblock = firstblock; + firstblock = NULL; + + state->currentblock = currentblock; + currentblock = NULL; + + state->cexcept_dobjstack = cexcept_dobjstack; + cexcept_dobjstack = NULL; + + state->sinit_label = sinit_label; + sinit_label = NULL; + + state->ainit_expr = ainit_expr; + ainit_expr = NULL; + + state->ctor_chain = ctor_chain; + ctor_chain = NULL; + + state->cinit_tempnodefunc = cinit_tempnodefunc; + cinit_tempnodefunc = NULL; + + state->trychain = trychain; + trychain = NULL; + + state->cparser_fileoffset = cparser_fileoffset; + state->symdecltoken = symdecltoken; + + state->functionbodyoffset = functionbodyoffset; + functionbodyoffset = 0; + + state->functionbodypath = functionbodypath; + functionbodypath = NULL; + + state->symdecloffset = symdecloffset; + symdecloffset = 0; + + state->symdeclend = symdeclend; + + state->sourceoffset = sourceoffset; + sourceoffset = 0; + + state->sourcefilepath = sourcefilepath; + sourcefilepath = NULL; + + state->curstmtvalue = curstmtvalue; + curstmtvalue = 0; + + state->name_obj_check = name_obj_check; + name_obj_check = NULL; + + state->check_arglist = check_arglist; + check_arglist = NULL; + + state->blockcount = blockcount; + blockcount = 0; + + state->localcount = localcount; + localcount = 0; + + state->tk = tk; + state->tkidentifier = tkidentifier; + + state->global_access = global_access; + + state->cexcept_hasdobjects = cexcept_hasdobjects; + cexcept_hasdobjects = 0; + + state->sinit_first_object = sinit_first_object; + sinit_first_object = NULL; + + state->ainit_only_one = ainit_only_one; + ainit_only_one = 0; + + state->cfunc_is_extern_c = cfunc_is_extern_c; + cfunc_is_extern_c = 0; + + state->temp_reference_init = temp_reference_init; + + return state; +} + +void CFunc_SetGlobalCompilerState(CFuncSave *state) { + if (state) { + CScope_RestoreScope(&state->scope); + + arguments = state->arguments; + locals = state->locals; + Labels = state->labels; + curstmt = state->curstmt; + firstblock = state->firstblock; + currentblock = state->currentblock; + cexcept_dobjstack = state->cexcept_dobjstack; + sinit_label = state->sinit_label; + ainit_expr = state->ainit_expr; + ctor_chain = state->ctor_chain; + cinit_tempnodefunc = state->cinit_tempnodefunc; + trychain = state->trychain; + name_obj_check = state->name_obj_check; + check_arglist = state->check_arglist; + curstmtvalue = state->curstmtvalue; + cparser_fileoffset = state->cparser_fileoffset; + symdecltoken = state->symdecltoken; + functionbodyoffset = state->functionbodyoffset; + functionbodypath = state->functionbodypath; + symdecloffset = state->symdecloffset; + symdeclend = state->symdeclend; + sourceoffset = state->sourceoffset; + sourcefilepath = state->sourcefilepath; + blockcount = state->blockcount; + tk = state->tk; + tkidentifier = state->tkidentifier; + global_access = state->global_access; + localcount = state->localcount; + cexcept_hasdobjects = state->cexcept_hasdobjects; + sinit_first_object = state->sinit_first_object; + ainit_only_one = state->ainit_only_one; + cfunc_is_extern_c = state->cfunc_is_extern_c; + temp_reference_init = state->temp_reference_init; + + unlocklheap(); + } +} + +void CFunc_Gen(Statement *stmt, Object *func, UInt8 unk) { + Boolean flag; + CI_FuncData packed; + + if ((TYPE_FUNC(func->type)->flags & FUNC_FLAGS_400000) && !anyerrors) { + CInline_PackIFunctionData(&packed, stmt, func); + flag = 1; + } else { + flag = 0; + } + + CInline_GenFunc(stmt, func, unk); + + if (flag) + CClass_DefineCovariantFuncs(func, &packed); +} + +static void CFunc_CheckCtorInitializer(TypeClass *tclass, CtorChain *chain) { + ObjMemberVar *ivar; + CtorChain *scan; + + if (tclass->mode != CLASS_MODE_1) { + for (ivar = tclass->ivars; ivar; ivar = ivar->next) { + if (IS_TYPE_REFERENCE(ivar->type)) { + for (scan = chain; scan; scan = scan->next) { + if (scan->what == CtorChain_MemberVar && scan->u.membervar == ivar) + break; + } + + if (!scan) + CError_Error(CErrorStr256, ivar->name->name); + } else if (CParser_IsConst(ivar->type, ivar->qual)) { + for (scan = chain; scan; scan = scan->next) { + if (scan->what == CtorChain_MemberVar && scan->u.membervar == ivar) + break; + } + + if (!scan && !IS_TYPE_CLASS(ivar->type)) + CError_Error(CErrorStr255, ivar->name->name); + } + } + } +} + +void CFunc_CheckClassCtors(TypeClass *tclass) { + CFunc_CheckCtorInitializer(tclass, NULL); +} + +static void CFunc_ParseCtorInitializer(void) { + CtorChain *chain; + ENodeList *args; + TypeClass *tclass; + ObjMemberVar *ivar; + ClassList *base; + VClassList *vbase; + ENode *expr; + Type *origtype; + + ctor_chain = NULL; + + if (tk == ':') { + do { + tclass = NULL; + switch ((tk = lex())) { + case TK_IDENTIFIER: + for (ivar = cscope_currentclass->ivars; ivar; ivar = ivar->next) { + if (ivar->name == tkidentifier && lookahead() == '(') + goto do_ivar; + } + for (base = cscope_currentclass->bases; base; base = base->next) { + if (base->base->classname == tkidentifier) { + if (lookahead() == '(') { + tclass = base->base; + tk = lex(); + } else { + tkidentifier = base->base->classname; + } + break; + } + } + break; + + case TK_COLON_COLON: + break; + + default: + CError_Error(CErrorStr212); + return; + } + + if (!tclass) + tclass = CClass_GetQualifiedClass(); + + if (tclass) { + for (vbase = cscope_currentclass->vbases; vbase; vbase = vbase->next) { + if (vbase->base == tclass) + break; + } + + if (vbase) { + for (chain = ctor_chain; chain; chain = chain->next) { + if (chain->what == CtorChain_VBase && chain->u.vbase == vbase) { + CError_Error(CErrorStr212); + return; + } + } + + chain = lalloc(sizeof(CtorChain)); + chain->what = CtorChain_VBase; + chain->u.vbase = vbase; + } else { + for (base = cscope_currentclass->bases; base; base = base->next) { + if (base->base == tclass) + break; + } + + if (base) { + for (chain = ctor_chain; chain; chain = chain->next) { + if (chain->what == CtorChain_Base && chain->u.base == base) { + CError_Error(CErrorStr212); + return; + } + } + + chain = lalloc(sizeof(CtorChain)); + chain->what = CtorChain_Base; + chain->u.base = base; + } else { + CError_Error(CErrorStr212); + return; + } + } + } else { + for (ivar = cscope_currentclass->ivars; ivar; ivar = ivar->next) { + if (ivar->name == tkidentifier) + break; + } + + if (ivar) { + do_ivar: + for (chain = ctor_chain; chain; chain = chain->next) { + if (chain->what == CtorChain_MemberVar && chain->u.membervar == ivar) + CError_Error(CErrorStr212); + } + + chain = lalloc(sizeof(CtorChain)); + chain->what = CtorChain_MemberVar; + chain->u.membervar = ivar; + } else { + CError_Error(CErrorStr212); + return; + } + + tk = lex(); + } + + if (tk != '(') { + CError_Error(CErrorStr114); + return; + } + + tk = lex(); + args = CExpr_ScanExpressionList(1); + + if (tk != ')') { + CError_Error(CErrorStr115); + return; + } + + switch (chain->what) { + case CtorChain_Base: + expr = CABI_MakeThisExpr(NULL, chain->u.base->offset); + chain->objexpr = CExpr_ConstructObject(chain->u.base->base, expr, args, 1, 0, 0, 0, 1); + break; + case CtorChain_VBase: + expr = CABI_MakeThisExpr(chain->u.vbase->base, chain->u.vbase->offset); + chain->objexpr = CExpr_ConstructObject(chain->u.vbase->base, expr, args, 1, 0, 0, 0, 1); + break; + case CtorChain_MemberVar: + expr = CABI_MakeThisExpr(cscope_currentclass, chain->u.membervar->offset); + expr->flags = chain->u.membervar->qual & ENODE_FLAG_QUALS; + switch (chain->u.membervar->type->type) { + case TYPECLASS: + chain->objexpr = CExpr_ConstructObject(TYPE_CLASS(chain->u.membervar->type), expr, args, 1, 1, 0, 1, 1); + break; + case TYPEARRAY: + if (args) { + CError_Error(CErrorStr212); + continue; + } + chain->objexpr = NULL; + break; + default: + if (!args) { + args = lalloc(sizeof(ENodeList)); + args->next = NULL; + args->node = CExpr_DoExplicitConversion(chain->u.membervar->type, chain->u.membervar->qual, NULL); + } + if (args->next) { + CError_Error(CErrorStr212); + return; + } + expr = makemonadicnode(expr, EINDIRECT); + expr->rtype = chain->u.membervar->type; + if (IS_TYPE_BITFIELD(origtype = expr->rtype)) { + expr->data.monadic = makemonadicnode(expr->data.monadic, EBITFIELD); + expr->data.monadic->rtype = origtype; + expr->rtype = TYPE_BITFIELD(origtype)->bitfieldtype; + } + + chain->objexpr = makediadicnode(expr, CExpr_AssignmentPromotion(args->node, expr->rtype, expr->flags, 1), EASS); + } + break; + default: + CError_FATAL(3286); + } + + chain->next = ctor_chain; + ctor_chain = chain; + } while ((tk = lex()) == ','); + } +} + +static void CFunc_FunctionRedefinedCheck(Object *func) { + if (TYPE_FUNC(func->type)->flags & FUNC_FLAGS_100) + CError_Error(CErrorStr333, func); + + if ((TYPE_FUNC(func->type)->flags & FUNC_FLAGS_2) && func->datatype != DINLINEFUNC) + CError_Error(CErrorStr333, func); + + TYPE_FUNC(func->type)->flags |= FUNC_FLAGS_2; +} + +static Object *CFunc_DeclareFuncName(char *str, HashNameNode *name) { + Object *obj; + Object *aliasobj; + DeclInfo di; + + memclrw(&di, sizeof(di)); + di.name = name; + di.storageclass = TK_STATIC; + di.qual = Q_CONST; + di.thetype = CDecl_NewArrayType(TYPE(&stchar), strlen(str) + 1); + + obj = CParser_NewGlobalDataObject(&di); + aliasobj = CParser_NewAliasObject(obj, 0); + obj->nspace = cscope_root; + obj->datatype = DDATA; + CFunc_NameLocalStaticDataObject(obj, obj->name->name); + + return aliasobj; +} + +void CFunc_ParseFuncDef(Object *func, DeclInfo *di, TypeClass *tclass, Boolean is_method, Boolean is_static, NameSpace *nspace) { + Boolean has_try; + Object *nameobj_func; + Object *nameobj_FUNCTION; + Object *nameobj_pretty; + char *prettyname; + Statement *stmt18; + Statement *stmt16; + Statement firstStmt; + DeclThing thing; + CScopeSave scope; + + nameobj_func = NULL; + nameobj_FUNCTION = NULL; + nameobj_pretty = NULL; + prettyname = NULL; + + CError_ASSERT(3373, IS_TYPE_FUNC(func->type)); + + CFunc_FunctionRedefinedCheck(func); + CParser_UpdateObject(func, di); + + if (!is_method) { + CScope_SetFunctionScope(func, &scope); + if (tclass) + cscope_current = tclass->nspace; + } else { + CScope_SetMethodScope(func, tclass, is_static, &scope); + } + + if (nspace) + cscope_current = nspace; + + if (cscope_currentclass) + CClass_MemberDef(func, cscope_currentclass); + + cfunc_is_extern_c = di->x4E; + + CError_ASSERT(3392, IS_TYPE_FUNC(func->type)); + if (di->x45 && (func->qual & Q_ASM)) + CError_Error(CErrorStr176); + + if (cparamblkptr->isPrecompiling == 1 && !(func->qual & Q_INLINE)) + CError_ErrorTerm(CErrorStr180); + + if (di->x49) + CError_Error(CErrorStr127); + + CFunc_FuncGenSetup(&firstStmt, func); + if (!IS_TYPE_VOID(TYPE_FUNC(func->type)->functype)) + IsCompleteType(TYPE_FUNC(func->type)->functype); + + SetupFunctionArguments(func, di, &firstStmt); + + stmt18 = curstmt; + CPrep_GetFileOffsetInfo2(&cparser_fileoffset, &sourceoffset, &sourcefilepath); + functionbodyoffset = sourceoffset; + firstStmt.sourceoffset = sourceoffset; + functionbodypath = sourcefilepath; + firstStmt.sourcefilepath = sourcefilepath; + + if (di->x45) + CFunc_AdjustOldStyleArgs(); + + if (di->x1C) + CScope_MergeNameSpace(cscope_current, di->x1C); + + if (tk == TK_TRY) { + tk = lex(); + has_try = 1; + } else { + has_try = 0; + } + + if (CClass_IsConstructor(func)) { + CError_ASSERT(3445, cscope_currentclass); + CFunc_ParseCtorInitializer(); + CFunc_CheckCtorInitializer(cscope_currentclass, ctor_chain); + } + + CPrep_TokenStreamFlush(); + + if (!(func->qual & Q_ASM)) { + if (tk == '{') { + if (!has_try) + tk = lex(); + } else { + CError_ErrorSkip(CErrorStr135); + has_try = 0; + } + + if (func->name) { + nameobj_func = CFunc_DeclareFuncName(func->name->name, GetHashNameNode("__func__")); + nameobj_FUNCTION = CFunc_DeclareFuncName(func->name->name, GetHashNameNode("__FUNCTION__")); + prettyname = CError_GetObjectName(func); + nameobj_pretty = CFunc_DeclareFuncName(prettyname, GetHashNameNode("__PRETTY_FUNCTION__")); + } + + if (!copts.cplusplus) + CFunc_ParseLocalDeclarationList(0, 0, 0, 0); + + thing.switchinfo = NULL; + thing.loopContinue = NULL; + thing.loopBreak = NULL; + thing.thetype = TYPE_FUNC(func->type)->functype; + thing.qual = TYPE_FUNC(func->type)->qual; + + if (has_try) { + CExcept_ScanTryBlock(&thing, CClass_IsConstructor(func) || CClass_IsDestructor(func)); + if (tk != 0) + CPrep_UnLex(); + tk = '}'; + } else { + while (tk != '}') + statement(&thing); + } + + stmt16 = curstmt; + + if (stmt16->type != ST_RETURN && stmt16->type != ST_GOTO) { + CPrep_GetFileOffsetInfo2(&cparser_fileoffset, &sourceoffset, &sourcefilepath); + CFunc_AppendStatement(ST_RETURN); + + curstmt->dobjstack = NULL; + curstmt->expr = NULL; + + if ( + (copts.cplusplus || copts.c9x) && + !strcmp(func->name->name, "main") && + TYPE_FUNC(func->type)->functype == TYPE(&stsignedint) + ) + curstmt->expr = intconstnode(TYPE(&stsignedint), 0); + + if ( + stmt16->type == ST_EXPRESSION && + stmt16->expr->type == EFUNCCALL && + stmt16->expr->rtype == &stvoid && + (stmt16->expr->flags & ENODE_FLAG_VOLATILE) + ) + curstmt->flags |= StmtFlag_8; + } + + CheckCLabels(); + + if (nameobj_func && (nameobj_func->flags & OBJECT_FLAGS_UNUSED)) + CInit_DeclareData(nameobj_func->u.alias.object, func->name->name, NULL, strlen(func->name->name) + 1); + if (nameobj_FUNCTION && (nameobj_FUNCTION->flags & OBJECT_FLAGS_UNUSED)) + CInit_DeclareData(nameobj_FUNCTION->u.alias.object, func->name->name, NULL, strlen(func->name->name) + 1); + if (nameobj_pretty && (nameobj_pretty->flags & OBJECT_FLAGS_UNUSED)) + CInit_DeclareData(nameobj_pretty->u.alias.object, prettyname, NULL, strlen(prettyname) + 1); + + if (!fatalerrors) { + if (CClass_IsConstructor(func)) + CABI_TransConstructor(func, stmt18, cscope_currentclass, NULL, has_try); + if (CClass_IsDestructor(func)) + CABI_TransDestructor(func, func, &firstStmt, cscope_currentclass, 0); + + CFunc_DestructorCleanup(&firstStmt); + CFunc_CodeCleanup(&firstStmt); + symdeclend = CPrep_GetFileOffsetInfo(&cparser_fileoffset); + CFunc_Gen(&firstStmt, func, di->x45); + } + } else { + if (tk == '{') { + in_assembler = 1; + tk = lex(); + in_assembler = 0; + } else { + CError_ErrorSkip(CErrorStr135); + } + + CFunc_ParseLocalDeclarationList(1, 0, 0, 0); + Assembler(func); + } + + if (tk != '}') + CError_Error(CErrorStr130); + + CScope_RestoreScope(&scope); +} + +void InitExpr_Register(ENode *expr, Object *object) { + InitExpr *initexpr; + InitExpr *scan; + + if ( + cparamblkptr->isPrecompiling == 1 && + object->sclass != TK_STATIC && + !(object->qual & (Q_20000 | Q_OVERLOAD)) + ) + { + CError_Error(CErrorStr180); + return; + } + + if (copts.suppress_init_code) + return; + + initexpr = galloc(sizeof(InitExpr)); + initexpr->next = NULL; + initexpr->object = object; + initexpr->expr = CInline_CopyExpression(expr, CopyMode1); + + if (init_expressions) { + scan = init_expressions; + while (scan->next) + scan = scan->next; + scan->next = initexpr; + } else { + init_expressions = initexpr; + } +} + +void CFunc_GenerateDummyFunction(Object *func) { + NameSpace *nspace; + Boolean saveDebugInfo; + Statement firstStmt; + + if (!anyerrors) { + nspace = CFunc_FuncGenSetup(&firstStmt, NULL); + + saveDebugInfo = copts.isGeneratingDebugInfo; + copts.isGeneratingDebugInfo = 0; + + CFunc_CodeCleanup(&firstStmt); + CFunc_Gen(&firstStmt, func, 0); + + cscope_current = nspace->parent; + copts.isGeneratingDebugInfo = saveDebugInfo; + } +} + +void CFunc_GenerateSingleExprFunc(Object *func, ENode *expr) { + NameSpace *nspace; + Boolean saveDebugInfo; + Statement firstStmt; + Statement *stmt; + + if (cparamblkptr->isPrecompiling == 1) { + CError_Error(CErrorStr180); + return; + } + + if (!anyerrors) { + nspace = CFunc_FuncGenSetup(&firstStmt, func); + + saveDebugInfo = copts.isGeneratingDebugInfo; + copts.isGeneratingDebugInfo = 0; + + stmt = CFunc_AppendStatement(ST_EXPRESSION); + stmt->expr = expr; + + CFunc_CodeCleanup(&firstStmt); + CInline_GenFunc(&firstStmt, func, 0); + + cscope_current = nspace->parent; + copts.isGeneratingDebugInfo = saveDebugInfo; + } +} + +void CFunc_GenerateDummyCtorFunc(Object *func, Object *real_ctor) { + ENode *expr; + NameSpace *nspace; + FuncArg *arg1; + FuncArg *arg0; + ENodeList *list; + Boolean saveDebugInfo; + Statement firstStmt; + Statement *stmt; + + if (cparamblkptr->isPrecompiling == 1) { + CError_Error(CErrorStr180); + return; + } + + if (!anyerrors) { + cscope_currentfunc = func; + + nspace = CFunc_FuncGenSetup(&firstStmt, func); + + saveDebugInfo = copts.isGeneratingDebugInfo; + copts.isGeneratingDebugInfo = 0; + + CFunc_SetupNewFuncArgs(func, TYPE_FUNC(func->type)->args); + + expr = CExpr_NewENode(EFUNCCALL); + expr->type = EFUNCCALL; + expr->cost = 200; + expr->rtype = TYPE(&void_ptr); + expr->data.funccall.funcref = CExpr_MakeObjRefNode(real_ctor, 0); + expr->data.funccall.functype = TYPE_FUNC(func->type); + + CError_ASSERT(3716, IS_TYPE_FUNC(real_ctor->type)); + CError_ASSERT(3717, TYPE_FUNC(real_ctor->type)->flags & FUNC_FLAGS_METHOD); + CError_ASSERT(3718, arg0 = TYPE_FUNC(real_ctor->type)->args); + CError_ASSERT(3720, arg1 = arg0->next); + CError_ASSERT(3721, arguments); + + list = lalloc(sizeof(ENodeList)); + expr->data.funccall.args = list; + list->node = create_objectnode(arguments->object); + + if (TYPE_METHOD(real_ctor->type)->theclass->flags & CLASS_FLAGS_20) { + CError_ASSERT(3727, arg1 = arg1->next); + CError_ASSERT(3728, arguments->next); + list->next = lalloc(sizeof(ENodeList)); + list = list->next; + list->node = create_objectnode(arguments->next->object); + } + + while (arg1) { + CError_ASSERT(3737, arg1->dexpr); + list->next = lalloc(sizeof(ENodeList)); + list = list->next; + list->node = CExpr_GetDefaultArgument(expr->data.funccall.funcref, arg1); + arg1 = arg1->next; + } + + list->next = NULL; + + stmt = CFunc_AppendStatement(ST_RETURN); + stmt->expr = expr; + + CFunc_CodeCleanup(&firstStmt); + CInline_GenFunc(&firstStmt, func, 0); + + cscope_current = nspace->parent; + cscope_currentfunc = NULL; + copts.isGeneratingDebugInfo = saveDebugInfo; + } +} diff --git a/compiler_and_linker/unsorted/CInit.c b/compiler_and_linker/unsorted/CInit.c index ccc534e..a76bdab 100644 --- a/compiler_and_linker/unsorted/CInit.c +++ b/compiler_and_linker/unsorted/CInit.c @@ -3,25 +3,21 @@ #include "compiler/CClass.h" #include "compiler/CDecl.h" #include "compiler/CError.h" +#include "compiler/CException.h" #include "compiler/CExpr.h" #include "compiler/CInline.h" #include "compiler/CInt64.h" #include "compiler/CMachine.h" #include "compiler/CParser.h" +#include "compiler/CPrec.h" #include "compiler/CPrep.h" #include "compiler/CPrepTokenizer.h" #include "compiler/CScope.h" #include "compiler/CompilerTools.h" +#include "compiler/ObjGenMachO.h" #include "compiler/objects.h" #include "compiler/types.h" -// TODO - move me!! -extern void PreComp_StaticData(Object *obj, void *data, OLinkList *list, SInt32 size); -extern void ObjGen_DeclareReadOnlyData(Object *obj, void *data, OLinkList *list, SInt32 size); -extern void ObjGen_DeclareData(Object *obj, void *data, OLinkList *list, SInt32 size); -extern void CExcept_RegisterDestructorObject(Object *obj, SInt32 offset, Object *dtor, Boolean flag); -extern void CExcept_RegisterLocalArray(Statement *stmt, Object *obj, Object *dtor, SInt32 count, SInt32 size); - TempNodeCB cinit_tempnodefunc; InitInfo *cinit_initinfo; static PooledString *cinit_stringlist; @@ -803,7 +799,7 @@ static void CInit_InitTypeArray(CInit_Stuff *s, CInit_Stuff2 *s2, TypePointer *t } } -static void CInit_InitTypeStruct(CInit_Stuff *s, CInit_Stuff2 *s2, TypeStruct *tstruct, UInt32 qual, Boolean errorflag) { +static void CInit_InitTypeStruct(CInit_Stuff *s, CInit_Stuff2 *s2, const TypeStruct *tstruct, UInt32 qual, Boolean errorflag) { StructMember *member; SInt32 start; Boolean flag; @@ -1257,7 +1253,7 @@ static ENode *CInit_RegisterDtorObject(Type *type, Object *dtor, ENode *objexpr) expr->data.funccall.args = lalloc(sizeof(ENodeList)); expr->data.funccall.args->node = objexpr; expr->data.funccall.args->next = lalloc(sizeof(ENodeList)); - expr->data.funccall.args->next->node = create_objectrefnode(CABI_GetDestructorObject(dtor, 1)); + expr->data.funccall.args->next->node = create_objectrefnode(CABI_GetDestructorObject(dtor, CABIDestroy1)); expr->data.funccall.args->next->next = lalloc(sizeof(ENodeList)); expr->data.funccall.args->next->next->node = create_objectrefnode(CInit_CreateStaticData(CInit_GetRegMemType())); expr->data.funccall.args->next->next->next = NULL; @@ -1266,7 +1262,7 @@ static ENode *CInit_RegisterDtorObject(Type *type, Object *dtor, ENode *objexpr) } static Boolean CInit_ConstructGlobalObject(Object *obj, TypeClass *tclass, ENode *valueexpr, SInt32 offset, Boolean flag) { - Object *ctor; + NameSpaceObjectList *ctor; Object *dtor; ENodeList *list; ENode *expr; @@ -1336,7 +1332,7 @@ static Boolean CInit_ConstructGlobalObject(Object *obj, TypeClass *tclass, ENode static Boolean CInit_ConstructAutoObject(TypeClass *tclass, ENode *expr, SInt32 offset, Boolean flag) { ENodeList *r30; ENode *r29; - Object *ctor; + NameSpaceObjectList *ctor; Object *dtor; Boolean r24; @@ -1920,7 +1916,7 @@ static void CInit_AutoInit(Type *type, ENode *valueexpr, Boolean flag) { copy = galloc(sizeof(TypePointer)); *TYPE_POINTER(copy) = *TYPE_POINTER(type); type = copy; - copy->size = type->size + 1; + type->size++; } expr = create_objectrefnode(cinit_initinfo->obj1C); if (!IS_TYPE_POINTER_ONLY(expr->rtype)) { @@ -2163,7 +2159,7 @@ Statement *CInit_ConstructClassArray(Statement *stmt, TypeClass *tclass, Object stmt = CFunc_AppendStatement(ST_EXPRESSION); if (dtor) - dtor_expr = create_objectrefnode(CABI_GetDestructorObject(dtor, 1)); + dtor_expr = create_objectrefnode(CABI_GetDestructorObject(dtor, CABIDestroy1)); else dtor_expr = nullnode(); @@ -2236,7 +2232,7 @@ static void CInit_InitializeClassArray(Object *obj, TypeClass *tclass, Boolean f expr = nullnode(); } else { if (dtor) - dtor_expr = create_objectrefnode(CABI_GetDestructorObject(dtor, 1)); + dtor_expr = create_objectrefnode(CABI_GetDestructorObject(dtor, CABIDestroy1)); else dtor_expr = nullnode(); expr = CExpr_FuncCallSix( @@ -2270,7 +2266,7 @@ static void CInit_InitializeClassArray(Object *obj, TypeClass *tclass, Boolean f CParser_RegisterSingleExprFunction(funcobj, funccallexpr( darr_func, create_objectrefnode(obj), - create_objectrefnode(CABI_GetDestructorObject(dtor, 1)), + create_objectrefnode(CABI_GetDestructorObject(dtor, CABIDestroy1)), intconstnode(TYPE(&stsignedlong), tclass->size), intconstnode(TYPE(&stsignedlong), count) )); @@ -2330,7 +2326,7 @@ static ENode *CInit_GlobalTempNode(Type *type, Boolean flag) { funcnode->data.funccall.args = lalloc(sizeof(ENodeList)); funcnode->data.funccall.args->node = node; funcnode->data.funccall.args->next = lalloc(sizeof(ENodeList)); - funcnode->data.funccall.args->next->node = create_objectrefnode(CABI_GetDestructorObject(dtor, 1)); + funcnode->data.funccall.args->next->node = create_objectrefnode(CABI_GetDestructorObject(dtor, CABIDestroy1)); funcnode->data.funccall.args->next->next = lalloc(sizeof(ENodeList)); funcnode->data.funccall.args->next->next->node = create_objectrefnode(CInit_CreateStaticData(CInit_GetRegMemType()));; funcnode->data.funccall.args->next->next->next = NULL; @@ -2641,7 +2637,7 @@ void CInit_InitializeAutoData(Object *obj, InsertExprCB insert_cb, RegisterObjec } if (IS_TYPE_CLASS(obj->type) && CClass_Destructor(TYPE_CLASS(obj->type))) - register_cb(obj->type, obj, 0, NULL); + register_cb(obj->type, obj, 0, 0); CInit_CleanupInitInfo(&initinfo); } diff --git a/compiler_and_linker/unsorted/CMangler.c b/compiler_and_linker/unsorted/CMangler.c index e3e3c3e..c1b9618 100644 --- a/compiler_and_linker/unsorted/CMangler.c +++ b/compiler_and_linker/unsorted/CMangler.c @@ -47,54 +47,54 @@ HashNameNode *CMangler_DeleteDtorName(void) { return GetHashNameNodeExport("__dt"); } -char *CMangler_GetOperator(HashNameNode *opname) { - char *name; +char *CMangler_GetOperator(HashNameNode *name) { + char *str; - if (opname == asop_name_node) + if (name == asop_name_node) return "operator="; - name = opname->name; - if (!strcmp(name, "__nw")) return "operator new"; - if (!strcmp(name, "__dl")) return "operator delete"; - if (!strcmp(name, "__nwa")) return "operator new[]"; - if (!strcmp(name, "__dla")) return "operator delete[]"; - if (!strcmp(name, "__pl")) return "operator+"; - if (!strcmp(name, "__mi")) return "operator-"; - if (!strcmp(name, "__ml")) return "operator*"; - if (!strcmp(name, "__dv")) return "operator/"; - if (!strcmp(name, "__md")) return "operator%"; - if (!strcmp(name, "__er")) return "operator^"; - if (!strcmp(name, "__ad")) return "operator&"; - if (!strcmp(name, "__or")) return "operator|"; - if (!strcmp(name, "__co")) return "operator~"; - if (!strcmp(name, "__nt")) return "operator!"; - if (!strcmp(name, "__lt")) return "operator<"; - if (!strcmp(name, "__gt")) return "operator>"; - if (!strcmp(name, "__apl")) return "operator+="; - if (!strcmp(name, "__ami")) return "operator-="; - if (!strcmp(name, "__amu")) return "operator*="; - if (!strcmp(name, "__adv")) return "operator/="; - if (!strcmp(name, "__amd")) return "operator%="; - if (!strcmp(name, "__aer")) return "operator^="; - if (!strcmp(name, "__aad")) return "operator&="; - if (!strcmp(name, "__aor")) return "operator|="; - if (!strcmp(name, "__ls")) return "operator<<"; - if (!strcmp(name, "__rs")) return "operator>>"; - if (!strcmp(name, "__als")) return "operator<<="; - if (!strcmp(name, "__ars")) return "operator>>="; - if (!strcmp(name, "__eq")) return "operator=="; - if (!strcmp(name, "__ne")) return "operator!="; - if (!strcmp(name, "__le")) return "operator<="; - if (!strcmp(name, "__ge")) return "operator>="; - if (!strcmp(name, "__aa")) return "operator&&"; - if (!strcmp(name, "__oo")) return "operator||"; - if (!strcmp(name, "__pp")) return "operator++"; - if (!strcmp(name, "__mm")) return "operator--"; - if (!strcmp(name, "__cm")) return "operator,"; - if (!strcmp(name, "__rm")) return "operator->*"; - if (!strcmp(name, "__rf")) return "operator*"; - if (!strcmp(name, "__cl")) return "operator()"; - if (!strcmp(name, "__vc")) return "operator[]"; + str = name->name; + if (!strcmp(str, "__nw")) return "operator new"; + if (!strcmp(str, "__dl")) return "operator delete"; + if (!strcmp(str, "__nwa")) return "operator new[]"; + if (!strcmp(str, "__dla")) return "operator delete[]"; + if (!strcmp(str, "__pl")) return "operator+"; + if (!strcmp(str, "__mi")) return "operator-"; + if (!strcmp(str, "__ml")) return "operator*"; + if (!strcmp(str, "__dv")) return "operator/"; + if (!strcmp(str, "__md")) return "operator%"; + if (!strcmp(str, "__er")) return "operator^"; + if (!strcmp(str, "__ad")) return "operator&"; + if (!strcmp(str, "__or")) return "operator|"; + if (!strcmp(str, "__co")) return "operator~"; + if (!strcmp(str, "__nt")) return "operator!"; + if (!strcmp(str, "__lt")) return "operator<"; + if (!strcmp(str, "__gt")) return "operator>"; + if (!strcmp(str, "__apl")) return "operator+="; + if (!strcmp(str, "__ami")) return "operator-="; + if (!strcmp(str, "__amu")) return "operator*="; + if (!strcmp(str, "__adv")) return "operator/="; + if (!strcmp(str, "__amd")) return "operator%="; + if (!strcmp(str, "__aer")) return "operator^="; + if (!strcmp(str, "__aad")) return "operator&="; + if (!strcmp(str, "__aor")) return "operator|="; + if (!strcmp(str, "__ls")) return "operator<<"; + if (!strcmp(str, "__rs")) return "operator>>"; + if (!strcmp(str, "__als")) return "operator<<="; + if (!strcmp(str, "__ars")) return "operator>>="; + if (!strcmp(str, "__eq")) return "operator=="; + if (!strcmp(str, "__ne")) return "operator!="; + if (!strcmp(str, "__le")) return "operator<="; + if (!strcmp(str, "__ge")) return "operator>="; + if (!strcmp(str, "__aa")) return "operator&&"; + if (!strcmp(str, "__oo")) return "operator||"; + if (!strcmp(str, "__pp")) return "operator++"; + if (!strcmp(str, "__mm")) return "operator--"; + if (!strcmp(str, "__cm")) return "operator,"; + if (!strcmp(str, "__rm")) return "operator->*"; + if (!strcmp(str, "__rf")) return "operator*"; + if (!strcmp(str, "__cl")) return "operator()"; + if (!strcmp(str, "__vc")) return "operator[]"; return NULL; } @@ -146,12 +146,12 @@ HashNameNode *CMangler_OperatorName(short token) { } } -HashNameNode *CMangler_VTableName(TypeClass *tclass) { +HashNameNode *CMangler_VTableName(TypeClass *theclass) { HashNameNode *name; name_mangle_list.size = 0; AppendGListName(&name_mangle_list, "__vt__"); - CMangler_MangleClassName(tclass); + CMangler_MangleClassName(theclass); AppendGListByte(&name_mangle_list, 0); COS_LockHandle(name_mangle_list.data); name = GetHashNameNodeExport(*name_mangle_list.data); @@ -172,20 +172,20 @@ HashNameNode *CMangler_RTTIObjectName(Type *type, UInt32 qual) { return name; } -HashNameNode *CMangler_ThunkName(Object *obj, int a, int b, int c) { +HashNameNode *CMangler_ThunkName(Object *vfunc, SInt32 this_delta, SInt32 return_delta, SInt32 ctoroffset) { HashNameNode *linkname; HashNameNode *name; char buf[64]; - linkname = CMangler_GetLinkName(obj); + linkname = CMangler_GetLinkName(vfunc); name_mangle_list.size = 0; - if (b == 0) { - if (c < 0) - sprintf(buf, "_@%ld@", -a); + if (return_delta == 0) { + if (ctoroffset < 0) + sprintf(buf, "_@%ld@", -this_delta); else - sprintf(buf, "_@%ld@%ld@", -a, c); + sprintf(buf, "_@%ld@%ld@", -this_delta, ctoroffset); } else { - sprintf(buf, "_@%ld@%ld@%ld@", -a, c, b); + sprintf(buf, "_@%ld@%ld@%ld@", -this_delta, ctoroffset, return_delta); } AppendGListName(&name_mangle_list, buf); AppendGListID(&name_mangle_list, linkname->name + 1); @@ -640,15 +640,14 @@ static HashNameNode *CMangler_FunctionLinkName(Object *obj) { return name; } -HashNameNode *CMangler_GetCovariantFunctionName(Object *obj, Type *type) { - HashNameNode *linkname; +HashNameNode *CMangler_GetCovariantFunctionName(Object *dobj, TypeClass *theclass) { HashNameNode *name; - linkname = CMangler_GetLinkName(obj); + name = CMangler_GetLinkName(dobj); name_mangle_list.size = 0; - AppendGListName(&name_mangle_list, linkname->name); + AppendGListName(&name_mangle_list, name->name); AppendGListName(&name_mangle_list, "@@"); - CMangler_MangleTypeAppend(type, 0); + CMangler_MangleTypeAppend(TYPE(theclass), 0); AppendGListByte(&name_mangle_list, 0); COS_LockHandle(name_mangle_list.data); diff --git a/compiler_and_linker/unsorted/CParser.c b/compiler_and_linker/unsorted/CParser.c index 8228159..85ccf26 100644 --- a/compiler_and_linker/unsorted/CParser.c +++ b/compiler_and_linker/unsorted/CParser.c @@ -8,46 +8,26 @@ #include "compiler/CInit.h" #include "compiler/CInline.h" #include "compiler/CInt64.h" +#include "compiler/CIRTransform.h" #include "compiler/CMachine.h" #include "compiler/CMangler.h" +#include "compiler/CObjC.h" #include "compiler/CPrep.h" #include "compiler/CPrepTokenizer.h" #include "compiler/CScope.h" +#include "compiler/CSOM.h" +#include "compiler/CTemplateNew.h" +#include "compiler/CTemplateTools.h" #include "compiler/CodeGen.h" #include "compiler/CompilerTools.h" +#include "compiler/IrOptimizer.h" +#include "compiler/IroPointerAnalysis.h" +#include "compiler/ObjGenMachO.h" #include "compiler/objects.h" #include "compiler/scopes.h" #include "compiler/templates.h" #include "cos.h" -// TODO MOVE ME -extern SInt32 symdecloffset; -extern void CSOM_Setup(Boolean is_precompiler); -extern void CSOM_Cleanup(void); -extern void CIRTrans_Setup(void); -extern void CObjC_Setup(void); -extern void CObjC_GenerateModule(void); -extern Type *CObjC_ParseTypeProtocol(Type *type); -extern void CObjC_ParseProtocol(void); -extern void CObjC_ParseClassDeclaration(void); -extern void CObjC_ParseInterface(void); -extern void CObjC_ParseImplementation(void); -extern void CTempl_Setup(void); -extern void CTempl_Parse(TypeClass *tclass, short access); -extern Boolean CTempl_Instantiate(void); -extern Boolean CInline_GenerateDeferredFuncs(void); -extern void CTempl_Cleanup(); -extern void CIRTrans_Cleanup(); -extern void CObjC_Cleanup(); -extern void PointerAnalysis_ParseFunctionModifiesSpecifier(DeclInfo *declinfo); -extern void PointerAnalysis_ParseExitPointsToSpecifier(DeclInfo *declinfo); -extern void PointerAnalysis_ParseEntryPointsToSpecifier(DeclInfo *declinfo); -extern Boolean CTemplTool_TemplDepTypeCompare(TypeTemplDep *a, TypeTemplDep *b); -extern Boolean CTemplTool_IsSameTemplateType(Type *a, Type *b); -extern TemplStack *ctempl_curinstance; -extern Type *CObjC_ParseID(void); -extern void CodeGen_UpdateOptimizerOptions(void); - FileOffsetInfo cparser_fileoffset; TStreamElement symdecltoken; ParserTryBlock *trychain; @@ -276,16 +256,14 @@ static void CParser_SetupRuntimeObjects(void) { func = CParser_NewRTFunc( TYPE(&stvoid), CMangler_OperatorName(TK_DELETE), 1, 1, &void_ptr); -#line 379 - CError_ASSERT(IS_TYPE_FUNC(func->type)); + CError_ASSERT(379, IS_TYPE_FUNC(func->type)); TYPE_FUNC(func->type)->exspecs = exspecs; CScope_AddGlobalObject(func); func = CParser_NewRTFunc( TYPE(&stvoid), CMangler_OperatorName(TK_DELETE_ARRAY), 1, 1, &void_ptr); -#line 387 - CError_ASSERT(IS_TYPE_FUNC(func->type)); + CError_ASSERT(387, IS_TYPE_FUNC(func->type)); TYPE_FUNC(func->type)->exspecs = exspecs; CScope_AddGlobalObject(func); @@ -374,8 +352,7 @@ static void CParser_SetupRuntimeObjects(void) { 1, &void_ptr); CodeGen_SetupRuntimeObjects(); -#line 534 - CError_ASSERT(CParser_ReInitRuntimeObjects(0)); + CError_ASSERT(534, CParser_ReInitRuntimeObjects(0)); } void CParser_Setup(void) { @@ -825,8 +802,7 @@ FuncArg *CParser_NewFuncArg(void) { Type *atomtype(void) { switch (tksize) { default: -#line 1145 - CError_FATAL(); + CError_FATAL(1145); case ATOM_VOID: return &stvoid; case ATOM_CHAR: return TYPE(&stchar); case ATOM_WCHAR: return TYPE(&stwchar); @@ -853,8 +829,8 @@ Object *CParser_FindDeallocationObject(Type *type, FuncArg *args, Boolean flag1, CScopeParseResult pr; Boolean first_time; Boolean retry_flag; - Type *sizet; Object *obj; + Type *sizet; list = NULL; *outflag = 0; @@ -867,13 +843,11 @@ Object *CParser_FindDeallocationObject(Type *type, FuncArg *args, Boolean flag1, mylist.object = pr.obj_10; list = &mylist; } else { -#line 1202 - CError_ASSERT(pr.nsol_14); + CError_ASSERT(1202, pr.nsol_14); list = pr.nsol_14; } } else if (TYPE_CLASS(type)->flags & CLASS_FLAGS_1) { -#line 1210 - CError_ASSERT(!args && !flag1); + CError_ASSERT(1210, !args && !flag1); return delh_func; } } @@ -894,8 +868,7 @@ Object *CParser_FindDeallocationObject(Type *type, FuncArg *args, Boolean flag1, return obj; } -#line 1231 - CError_ASSERT(first_time); + CError_ASSERT(1231, first_time); sizet = CABI_GetSizeTType(); for (scan = list; scan; scan = scan->next) { @@ -1014,19 +987,14 @@ short is_memberpointerequal(Type *a, Type *b) { if ((TYPE_FUNC(a)->flags & (FUNC_FLAGS_F0000000 | FUNC_FLAGS_PASCAL)) != (TYPE_FUNC(b)->flags & (FUNC_FLAGS_F0000000 | FUNC_FLAGS_PASCAL))) return 0; -#line 1345 - CError_ASSERT((arg_a = TYPE_FUNC(a)->args)); - CError_ASSERT((arg_b = TYPE_FUNC(b)->args)); + CError_ASSERT(1345, arg_a = TYPE_FUNC(a)->args); + CError_ASSERT(1346, arg_b = TYPE_FUNC(b)->args); - if (TYPE_FUNC(a)->flags & FUNC_FLAGS_80) { -#line 1351 - CError_ASSERT((arg_a = arg_a->next)); - } + if (TYPE_FUNC(a)->flags & FUNC_FLAGS_80) + CError_ASSERT(1351, arg_a = arg_a->next); - if (TYPE_FUNC(b)->flags & FUNC_FLAGS_80) { -#line 1355 - CError_ASSERT((arg_b = arg_b->next)); - } + if (TYPE_FUNC(b)->flags & FUNC_FLAGS_80) + CError_ASSERT(1355, arg_b = arg_b->next); if (arg_a->qual != arg_b->qual) return 0; @@ -1082,8 +1050,7 @@ restart: case TYPETEMPLATE: return CTemplTool_TemplDepTypeCompare(TYPE_TEMPLATE(a), TYPE_TEMPLATE(b)); default: -#line 1441 - CError_FATAL(); + CError_FATAL(1441); return 0; } } @@ -1135,8 +1102,7 @@ short iscpp_typeequal(Type *a, Type *b) { case TYPETEMPLATE: return CTemplTool_TemplDepTypeCompare(TYPE_TEMPLATE(a), TYPE_TEMPLATE(b)); default: -#line 1500 - CError_FATAL(); + CError_FATAL(1500); return 0; } } @@ -1311,10 +1277,9 @@ restart: return 0; if ((TYPE_FUNC(a)->flags & (FUNC_FLAGS_F0000000 | FUNC_FLAGS_PASCAL)) != (TYPE_FUNC(b)->flags & (FUNC_FLAGS_F0000000 | FUNC_FLAGS_PASCAL))) return 0; - return is_arglistequal(TYPE_FUNC(a)->args, TYPE_FUNC(b)->args); + return is_arglistsame(TYPE_FUNC(a)->args, TYPE_FUNC(b)->args); default: -#line 1709 - CError_FATAL(); + CError_FATAL(1709); return 0; } } @@ -1336,8 +1301,7 @@ Type *CParser_GetWCharType(void) { short CParser_GetOperator(ENodeType t) { switch (t) { default: -#line 1748 - CError_FATAL(); + CError_FATAL(1748); case EMONMIN: return '-'; case EBINNOT: return '~'; case ELOGNOT: return '!'; @@ -1757,7 +1721,7 @@ Boolean CParserIsVolatileExpr(ENode *expr) { return CParser_IsVolatile(expr->rtype, expr->flags & ENODE_FLAG_QUALS); } -Boolean CParser_HasInternalLinkage(Object *obj) { +Boolean CParser_HasInternalLinkage(const Object *obj) { NameSpace *nspace; for (nspace = obj->nspace; nspace; nspace = nspace->parent) { @@ -1769,24 +1733,26 @@ Boolean CParser_HasInternalLinkage(Object *obj) { return 1; if (obj->qual & (Q_20000 | Q_OVERLOAD)) return 0; - if (obj->sclass == OBJECT_SCLASS_102) + if (obj->sclass == TK_STATIC) return 1; + // this feels *wrong* but it's the only way to match this function that I can see if (obj->qual & Q_INLINE) - obj->qual |= Q_20000; + ((Object *) obj)->qual |= Q_20000; return 0; } -Boolean CParser_HasInternalLinkage2(Object *obj) { +Boolean CParser_HasInternalLinkage2(const Object *obj) { if (obj->datatype == DLOCAL) return 1; if (obj->qual & (Q_20000 | Q_OVERLOAD)) return 0; - if (obj->sclass == OBJECT_SCLASS_102) + if (obj->sclass == TK_STATIC) return 1; + // this feels *wrong* but it's the only way to match this function that I can see if (obj->qual & Q_INLINE) - obj->qual |= Q_20000; + ((Object *) obj)->qual |= Q_20000; return 0; } @@ -2036,8 +2002,7 @@ void CParser_ParseAttribute(Type *type, DeclInfo *declinfo) { declinfo->qual |= Q_ALIGNED_8192; break; default: -#line 2779 - CError_FATAL(); + CError_FATAL(2779); break; } } else { @@ -2638,10 +2603,10 @@ void CParser_GetDeclSpecs(DeclInfo *di, Boolean flag) { SInt32 state; CScopeParseResult pr; - di->fileoffsetinfo.file = CPrep_BrowserCurrentFile(); + di->file = CPrep_BrowserCurrentFile(); CPrep_BrowserFilePosition( - (CPrepFileInfo **) &di->fileoffsetinfo.tokenline, - &di->fileoffsetinfo.tokenoffset); + (CPrepFileInfo **) &di->file2, + &di->x60); r24 = 1; r23 = copts.cplusplus; @@ -2940,8 +2905,7 @@ restart: pr.x8 = TYPE(&stsignedint); break; default: -#line 4109 - CError_FATAL(); + CError_FATAL(4109); } break; case TEMPLDEP_QUALNAME: @@ -2954,8 +2918,7 @@ restart: case TEMPLDEP_BITFIELD: break; default: -#line 4136 - CError_FATAL(); + CError_FATAL(4136); } } @@ -2980,7 +2943,7 @@ restart: typetoken = -1; tk = lex(); if (tk == '<' && copts.objective_c && IS_TYPE_CLASS(di->thetype) && TYPE_CLASS(di->thetype)->objcinfo) - di->thetype = CObjC_ParseTypeProtocol(di->thetype); + di->thetype = CObjC_ParseTypeProtocol(TYPE_CLASS(di->thetype)); goto bailOut; } else if (pr.nsol_14) { if (pr.x1D) { @@ -3010,8 +2973,7 @@ restart: CError_Error(121); break; default: -#line 4217 - CError_FATAL(); + CError_FATAL(4217); } } else if (pr.name_4) { if (copts.cplusplus) @@ -3022,8 +2984,7 @@ restart: tk = lex(); r23 = 0; } else { -#line 4234 - CError_FATAL(); + CError_FATAL(4234); } } } @@ -3216,8 +3177,7 @@ void CParser_CallBackAction(Object *obj) { } } -#line 4551 - CError_FATAL(); + CError_FATAL(4551); } static Object *CParser_FindOverloadFunc(NameSpaceObjectList *list, TypeFunc *tfunc) { diff --git a/compiler_and_linker/unsorted/CPrec.c b/compiler_and_linker/unsorted/CPrec.c index f835c6c..6e0692b 100644 --- a/compiler_and_linker/unsorted/CPrec.c +++ b/compiler_and_linker/unsorted/CPrec.c @@ -1,6 +1,17 @@ -#include "compiler.h" -#include "compiler/CompilerTools.h" +#include "compiler/CPrec.h" #include "compiler/CError.h" +#include "compiler/CFunc.h" +#include "compiler/CInit.h" +#include "compiler/CInline.h" +#include "compiler/CMachine.h" +#include "compiler/CObjC.h" +#include "compiler/CParser.h" +#include "compiler/CPrep.h" +#include "compiler/CScope.h" +#include "compiler/CSOM.h" +#include "compiler/CTemplateNew.h" +#include "compiler/CompilerTools.h" +#include "compiler/Exceptions.h" #include "compiler/enode.h" #include "compiler/objc.h" #include "compiler/objects.h" @@ -9,84 +20,90 @@ #include "compiler/templates.h" #include "compiler/types.h" #include "cos.h" - -// HACKS -extern Type stvoid; -extern Type stbool; -extern Type stchar; -extern Type stsignedchar; -extern Type stunsignedchar; -extern Type stwchar; -extern Type stsignedshort; -extern Type stunsignedshort; -extern Type stsignedint; -extern Type stunsignedint; -extern Type stsignedlong; -extern Type stunsignedlong; -extern Type stsignedlonglong; -extern Type stunsignedlonglong; -extern Type stfloat; -extern Type stshortdouble; -extern Type stdouble; -extern Type stlongdouble; -extern Type elipsis; -extern Type oldstyle; -extern Type stillegal; -extern Type sttemplexpr; -extern Type stvoid; -extern Type void_ptr; -extern Type rt_func; -extern Type catchinfostruct; -extern void * newh_func; -extern void * delh_func; -extern void * copy_func; -extern void * clear_func; -extern void * Rgtid_func; -extern void * Rdync_func; -extern void * rt_ptmf_cast; -extern void * rt_ptmf_cmpr; -extern void * rt_ptmf_test; -extern void * rt_ptmf_call; -extern void * rt_ptmf_scall; -extern void * rt_ptmf_null; -extern void * rt_som_glue1; -extern void * rt_som_glue2; -extern void * rt_som_glue3; -extern void * rt_som_check; -extern void * rt_som_new; -extern void * rt_som_newcheck; -extern void * rt_ptmf_call4; -extern void * rt_ptmf_scall4; -extern void * carr_func; -extern void * cnar_func; -extern void * darr_func; -extern void * dnar_func; -extern void * dnar3_func; -extern void * Xgreg_func; -extern void * Xthrw_func; -extern void * Xicth_func; -extern void * Xecth_func; -extern void * Xunex_func; -extern Type stvectorunsignedchar; -extern Type stvectorsignedchar; -extern Type stvectorboolchar; -extern Type stvectorunsignedshort; -extern Type stvectorsignedshort; -extern Type stvectorboolshort; -extern Type stvectorunsignedlong; -extern Type stvectorsignedlong; -extern Type stvectorboollong; -extern Type stvectorfloat; -extern Type stvectorpixel; -// HACKS - -// PUBLIC FUNCTIONS -extern void SetupPrecompiler(); -extern void CleanupPrecompiler(); -extern void PreComp_StaticData(Object *obj, const void *data, void *unk1, void *unk2); -extern void PrecompilerWrite(); -extern void PrecompilerRead(short refnum, void *buffer); -// END PUBLIC FUNCTIONS +#include "compiler/CCompiler.h" +#include "compiler/InlineAsm.h" + +#define RESOLVE_BUFFER(offset) ((void *) (((char *) cprec_buffer) + ((uintptr_t) (offset)))) +#define RESOLVE_RAW_BUFFER(offset) ((void *) (((char *) cprec_rawbuffer) + ((uintptr_t) (offset)))) +#define RESOLVE_SAFE(offset) (!(offset) ? NULL : ((void *) (((char *) cprec_rawbuffer) + ((uintptr_t) (offset))))) + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +typedef struct StaticData { + struct StaticData *next; + Object *object; + void *buffer; + OLinkList *links; + SInt32 size; +} StaticData; + +typedef struct Header { + UInt32 magic; + UInt16 version; + UInt16 x6; + char target; + Boolean check_header_flags; + Boolean cplusplus; + UInt32 xC; + UInt32 x10; + UInt32 x14; + UInt32 x18; + UInt32 x1C; + UInt32 x20; + UInt32 x24; + UInt32 x28; + UInt32 x2C; + UInt32 x30; + UInt32 compressedPatchCount; + UInt32 compressedPatchSize; + UInt32 compressedPatchOffset; + UInt32 builtinPatchSize; + UInt32 builtinPatchOffset; + UInt32 tokenStreamPatchSize; + UInt32 tokenStreamPatchOffset; + UInt32 root_names; + NameSpaceList *usings; + TemplClass *ctempl_templates; + CSOMStub *csom_stubs; + StaticData *cprec_staticdata; + UInt32 uniqueID; + CallbackAction *callbackactions; + Type *cobjc_type_class; + Type *cobjc_type_id; + Type *cobjc_type_sel; + ObjCSelector **cobjc_selhashtable; + BClassList *cobjc_classdefs; + ObjCProtocol *cobjc_protocols; + UInt32 cobjc_selrefcount; + UInt32 cobjc_classrefcount; + UInt32 cobjc_stringcount; + InitExpr *init_expressions; + CI_Action *cinline_tactionlist; + TemplateFunction *ctempl_templatefuncs; + UInt32 x9C; + UInt32 xA0; + UInt32 xA4; + UInt32 xA8; + UInt32 xAC; + UInt32 xB0; + UInt32 xB4; + UInt32 xB8; + UInt32 xBC; + UInt32 xC0; + UInt32 xC4; + UInt32 xC8; + UInt32 xCC; + UInt32 xD0; + UInt32 xD4; + UInt32 xD8; + UInt32 xDC; + UInt32 xE0; + UInt32 xE4; + HashNameNode *nametable[0x800]; + Macro *macrotable[0x800]; + NameSpaceName *root_nametable[0x400]; +} Header; typedef struct Patch { struct Patch *next; @@ -121,31 +138,41 @@ typedef struct TokenPatch { SInt32 count; } TokenPatch; static TokenPatch *cprec_tokenpatches; +static StaticData *cprec_staticdata; + +typedef struct PointerHash { + struct PointerHash *next; + TypePointer *tptr; + TypePointer *prec_tptr; +} PointerHash; +static PointerHash **cprec_pointerhash; -static void *cprec_staticdata; -static void *cprec_pointerhash; static BuiltIn *cprec_builtin; static Patch *cprec_patch_list; static AddrPatch **cprec_addrhash; -static void *cprec_header; +static Header *cprec_header; static GList cprec_glist; static short cprec_refnum; char *precomp_target_str; +#ifdef __MWERKS__ +#pragma options align=reset +#endif // Assorted forward declarations static NameSpace *CPrec_GetNameSpacePatch(NameSpace *nspace); static ObjEnumConst *CPrec_GetObjEnumConstPatch(ObjEnumConst *obj); static Object *CPrec_GetObjectPatch(Object *obj); static ObjBase *CPrec_GetObjBasePatch(ObjBase *obj); -static ObjMemberVar *CPrec_GetObjMemberVarPatch(ObjMemberVar *obj); +static ObjMemberVar *CPrec_GetObjMemberVarPatch(ObjMemberVar *ivar); static Type *CPrec_GetTypePatch(Type *type); -static ENode *CPrec_GetExpressionPatch(ENode *enode); +static ENode *CPrec_GetExpressionPatch(ENode *expr); static ObjCMethod *CPrec_GetObjCMethodPatch(ObjCMethod *meth); static ObjCProtocolList *CPrec_GetObjCProtocolListPatch(ObjCProtocolList *lst); static TemplArg *CPrec_GetTemplateArgPatch(TemplArg *arg); -static OSErr CPrec_FlushBufferCheck(); +static NameSpaceObjectList *CPrec_GetNameSpaceObjectListPatch(NameSpaceObjectList *nsol); +static OSErr CPrec_FlushBufferCheck(void); -void SetupPrecompiler() { +void SetupPrecompiler(void) { cprec_refnum = 0; cprec_glist.data = NULL; cprec_header = NULL; @@ -153,7 +180,7 @@ void SetupPrecompiler() { cprec_ioerror = noErr; } -void CleanupPrecompiler() { +void CleanupPrecompiler(void) { if (cprec_refnum) { COS_FileClose(cprec_refnum); cprec_refnum = 0; @@ -163,20 +190,49 @@ void CleanupPrecompiler() { FreeGList(&cprec_glist); } -static void CPrec_OLinkListCopy() {} +static OLinkList *CPrec_OLinkListCopy(OLinkList *list) { + OLinkList *copy; + + if (!list) + return NULL; + + copy = galloc(sizeof(OLinkList)); + *copy = *list; + copy->next = CPrec_OLinkListCopy(copy->next); + return copy; +} + +void PreComp_StaticData(Object *obj, const void *data, OLinkList *links, SInt32 size) { + StaticData *entry; + + if (obj->sclass != TK_STATIC && !(obj->qual & (Q_20000 | Q_OVERLOAD))) + CError_Error(CErrorStr180); -void PreComp_StaticData(Object *obj, const void *data, void *unk1, void *unk2) { + entry = galloc(sizeof(StaticData)); + entry->object = obj; + entry->size = size; + entry->next = cprec_staticdata; + cprec_staticdata = entry; + + if (data) { + entry->buffer = galloc(obj->type->size); + memcpy(entry->buffer, data, obj->type->size); + } else { + entry->buffer = NULL; + } + + entry->links = CPrec_OLinkListCopy(links); } -static void CPrec_InitAddressHashTable() { +static void CPrec_InitAddressHashTable(void) { cprec_addrhash = lalloc(0x4000 * sizeof(AddrPatch *)); memclrw(cprec_addrhash, 0x4000 * sizeof(AddrPatch *)); } -static void CPrec_InitPointerHashTable() { - cprec_pointerhash = lalloc(0x1000); - memclrw(cprec_pointerhash, 0x1000); +static void CPrec_InitPointerHashTable(void) { + cprec_pointerhash = lalloc(0x400 * sizeof(PointerHash *)); + memclrw(cprec_pointerhash, 0x400 * sizeof(PointerHash *)); } static int CPrec_AddressHashVal(void *addr) { @@ -214,7 +270,7 @@ static AddrPatch *CPrec_NewAddrPatch(void *addr, void *value) { return patch; } -static void CPrec_SetupBuiltInArray() { +static void CPrec_SetupBuiltInArray(void) { int count1, count2; Boolean flag; void **array; @@ -303,7 +359,7 @@ static void CPrec_SetupBuiltInArray() { } } -static void CPrec_SetupBuiltIn() { +static void CPrec_SetupBuiltIn(void) { int x; CPrec_SetupBuiltInArray(); @@ -321,13 +377,11 @@ static void CPrec_NewPointerPatch(void *src, void *ptr) { if (cprec_dowrite) { Patch *patch = lalloc(sizeof(Patch)); patch->offset = (SInt32) src; -#line 507 - CError_ASSERT((patch->offset & 0x80000001) == 0); + CError_ASSERT(507, (patch->offset & 0x80000001) == 0); if ((SInt32) ptr < 0) { ptr = (void *) ~((SInt32) ptr); -#line 513 - CError_ASSERT((SInt32) ptr < cprec_builtins); + CError_ASSERT(513, (SInt32) ptr < cprec_builtins); patch->next = cprec_builtin[(SInt32) ptr].patches; cprec_builtin[(SInt32) ptr].patches = patch; @@ -338,8 +392,7 @@ static void CPrec_NewPointerPatch(void *src, void *ptr) { } src = (void *)((char *) src - cprec_zero_offset); -#line 525 - CError_ASSERT((SInt32) src >= 0 && (SInt32) src <= cprec_glist.size); + CError_ASSERT(525, (SInt32) src >= 0 && (SInt32) src <= cprec_glist.size); *((void **) (*cprec_glist.data + (SInt32) src)) = ptr; } } @@ -349,21 +402,17 @@ static void CPrec_ExistingPointerPatch(void *src, void *ptr) { AddrPatch *addrPatch; Patch *patch; - addrPatch = CPrec_FindAddrPatch(ptr); -#line 543 - CError_ASSERT(addrPatch); + CError_ASSERT(543, addrPatch = CPrec_FindAddrPatch(ptr)); patch = lalloc(sizeof(Patch)); patch->offset = (SInt32) src; patch->next = cprec_patch_list; cprec_patch_list = patch; -#line 548 - CError_ASSERT((patch->offset & 0x80000001) == 0); + CError_ASSERT(548, (patch->offset & 0x80000001) == 0); src = (void *)((char *) src - cprec_zero_offset); -#line 552 - CError_ASSERT((SInt32) src >= 0 && (SInt32) src <= cprec_glist.size); + CError_ASSERT(552, (SInt32) src >= 0 && (SInt32) src <= cprec_glist.size); *((void **) (*cprec_glist.data + (SInt32) src)) = addrPatch->value; } } @@ -373,7 +422,7 @@ static void CPrec_NamePatch(void *src, HashNameNode *name) { CPrec_ExistingPointerPatch(src, name); } -static void *CPrec_AppendAlign() { +static void *CPrec_AppendAlign(void) { if (cprec_dowrite) { while (cprec_offset & 3) { AppendGListByte(&cprec_glist, 0); @@ -421,17 +470,14 @@ static UInt32 CPrec_AppendPointerPatch(void *v) { AddrPatch *addrPatch; if (v) { - addrPatch = CPrec_FindAddrPatch(v); -#line 644 - CError_ASSERT(addrPatch); + CError_ASSERT(644, addrPatch = CPrec_FindAddrPatch(v)); if (cprec_dowrite) { Patch *patch = lalloc(sizeof(Patch)); patch->offset = cprec_offset; patch->next = cprec_patch_list; cprec_patch_list = patch; -#line 651 - CError_ASSERT((patch->offset & 0x80000001) == 0); + CError_ASSERT(651, (patch->offset & 0x80000001) == 0); } return CPrec_AppendPointer(addrPatch->value); @@ -466,9 +512,141 @@ static void CPrec_RawMemPatch(void *source, const void *data, int len) { CPrec_NewPointerPatch(source, ptr); } -static void CPrec_DumpNameTable() {} -static void CPrec_DumpMacroTable() {} -static void CPrec_GetClassAccessPatch() {} +static void CPrec_DumpNameTable(void) { + HashNameNode *name; + int i; + HashNameNode *p; + HashNameNode *next; + + if (cprec_dowrite) { + i = 0; + do { + name = name_hash_nodes[i]; + while (name && name->id == 0) + name = name->next; + + if (name) { + p = CPrec_AppendAlign(); + cprec_header->nametable[i] = p; + + while (1) { + CPrec_NewAddrPatch(name, p); + CPrec_AppendPointer(NULL); + CPrec_AppendWord32(0); + CPrec_AppendWord16(name->hashval); + CPrec_AppendString(name->name); + + name = name->next; + while (name && name->id == 0) + name = name->next; + + if (!name) + break; + + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(&p->next, next); + p = next; + } + } + } while (++i < 0x800); + } else { + i = 0; + do { + if ((name = name_hash_nodes[i])) { + p = CPrec_AppendAlign(); + while (1) { + CPrec_NewAddrPatch(name, p); + CPrec_AppendPointer(NULL); + CPrec_AppendWord32(0); + CPrec_AppendWord16(name->hashval); + CPrec_AppendString(name->name); + + name = name->next; + if (!name) + break; + + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(&p->next, next); + p = next; + } + } + } while (++i < 0x800); + } +} + +static void CPrec_DumpMacroTable(void) { + Macro *macro; + int i; + int j; + Macro *p; + Macro *next; + + i = 0; + do { + for (macro = macrohashtable[i]; macro; macro = macro->next) { + if (macro->c) { + CPrec_NewAddrPatch(macro->c, (void *) cprec_offset); + CPrec_AppendString(macro->c); + } + } + } while (++i < 0x800); + + i = 0; + do { + macro = macrohashtable[i]; + + if (macro) { + p = CPrec_AppendAlign(); + if (cprec_dowrite) + cprec_header->macrotable[i] = p; + + while (1) { + CPrec_AppendPointer(NULL); + CPrec_AppendNamePatch(macro->name); + CPrec_AppendPointerPatch(macro->c); + CPrec_AppendWord16(macro->xC); + CPrec_AppendByte(macro->is_special); + CPrec_AppendByte(macro->xF); + + for (j = 1; j < (macro->xC & 0x7FFF); j++) + CPrec_AppendNamePatch(macro->names[j - 1]); + + macro = macro->next; + if (!macro) + break; + + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(&p->next, next); + p = next; + } + } + } while (++i < 0x800); +} + +static BClassList *CPrec_GetClassAccessPatch(BClassList *path) { + AddrPatch *addrPatch; + BClassList *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(path))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(path, first); + + while (1) { + CPrec_AppendData(path, sizeof(BClassList)); + CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch(path->type)); + if (!path->next) + break; + + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + path = path->next; + } + + return first; +} static int CPrec_PointerHash(TypePointer *type) { Type *target; @@ -517,8 +695,54 @@ restart: return (work + (work >> 24) + (work >> 16) + (work >> 8)) & 0x3FF; } -static TypePointer *CPrec_GetTypePointerPatch(TypePointer *type) { - // requires copts +static TypePointer *CPrec_GetTypePointerPatch(TypePointer *tptr) { + TypePointer *p; + int hash; + PointerHash *phash; + TypePointer *scan1; + TypePointer *scan2; + + if (tptr->qual & Q_100000) { + p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(tptr, p); + CPrec_AppendData(tptr, sizeof(TypeObjCID)); + if (TYPE_OBJC_ID(tptr)->protocols) + CPrec_NewPointerPatch(&TYPE_OBJC_ID(p)->protocols, CPrec_GetObjCProtocolListPatch(TYPE_OBJC_ID(tptr)->protocols)); + } else { + if (!copts.faster_pch_gen && cprec_dowrite && tptr->size > 0) { + hash = CPrec_PointerHash(tptr); + for (phash = cprec_pointerhash[hash]; phash; phash = phash->next) { + scan1 = tptr; + scan2 = phash->tptr; + check_again: + if (scan1->type == scan2->type && scan1->size == scan2->size && scan1->qual == scan2->qual) { + scan1 = TYPE_POINTER(TPTR_TARGET(scan1)); + scan2 = TYPE_POINTER(TPTR_TARGET(scan2)); + if (scan1->type == TYPEPOINTER && scan1->type == TYPEARRAY) + goto check_again; + if (scan1 == scan2) + return phash->prec_tptr; + } + } + + p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(tptr, p); + + phash = lalloc(sizeof(PointerHash)); + phash->tptr = tptr; + phash->prec_tptr = p; + phash->next = cprec_pointerhash[hash]; + cprec_pointerhash[hash] = phash; + } else { + p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(tptr, p); + } + + CPrec_AppendData(tptr, sizeof(TypePointer)); + } + + CPrec_NewPointerPatch(&p->target, CPrec_GetTypePatch(tptr->target)); + return p; } static TypeEnum *CPrec_GetTypeEnumPatch(TypeEnum *type) { @@ -541,15 +765,48 @@ static TypeEnum *CPrec_GetTypeEnumPatch(TypeEnum *type) { static TypeBitfield *CPrec_GetTypeBitfieldPatch(TypeBitfield *type) { TypeBitfield *p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(type, p); CPrec_AppendData(type, sizeof(TypeBitfield)); - - CPrec_NewPointerPatch(&p->bitfieldtype, type->bitfieldtype); + CPrec_NewPointerPatch(&p->bitfieldtype, CPrec_GetTypePatch(type->bitfieldtype)); return p; } -static TypeStruct *CPrec_GetTypeStructPatch(TypeStruct *type) {} +static TypeStruct *CPrec_GetTypeStructPatch(TypeStruct *tstruct) { + StructMember *member; + TypeStruct *p; + StructMember *current, *next; + + p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(tstruct, p); + CPrec_AppendData(tstruct, sizeof(TypeStruct)); + + if (tstruct->name) + CPrec_NamePatch(&p->name, tstruct->name); + + if ((member = tstruct->members)) { + current = CPrec_AppendAlign(); + CPrec_NewPointerPatch(&p->members, current); + + while (1) { + CPrec_AppendData(member, sizeof(StructMember)); + CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch(member->type)); + CPrec_NamePatch(¤t->name, member->name); + + if (!member->next) + break; + + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + + member = member->next; + } + } + + return p; +} static ExceptSpecList *CPrec_GetExceptSpecPatch(ExceptSpecList *exspec) { ExceptSpecList *first, *current, *next; @@ -572,40 +829,40 @@ static ExceptSpecList *CPrec_GetExceptSpecPatch(ExceptSpecList *exspec) { } static FuncArg *CPrec_GetArgListPatch(FuncArg *lst, Boolean includeNames) { - // too many register swaps - AddrPatch *addrPatch; FuncArg *first, *current, *next; + AddrPatch *addrPatch; if ((addrPatch = CPrec_FindAddrPatch(lst))) return addrPatch->value; first = current = CPrec_AppendAlign(); -restart: - if (!includeNames) - lst->name = NULL; - CPrec_AppendData(lst, sizeof(FuncArg)); - if (includeNames && lst->name) - CPrec_NamePatch(¤t->name, lst->name); - - if (lst->dexpr) - CPrec_NewPointerPatch(¤t->dexpr, CPrec_GetExpressionPatch(lst->dexpr)); - if (lst->type) - CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch(lst->type)); - else -#line 1167 - CError_FATAL(); + while (1) { + if (!includeNames) + lst->name = NULL; + CPrec_AppendData(lst, sizeof(FuncArg)); + if (includeNames && lst->name) + CPrec_NamePatch(¤t->name, lst->name); + + if (lst->dexpr) + CPrec_NewPointerPatch(¤t->dexpr, CPrec_GetExpressionPatch(lst->dexpr)); + if (lst->type) + CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch(lst->type)); + else + CError_FATAL(1167); + + if (!lst->next) + break; - if (lst->next) { if ((addrPatch = CPrec_FindAddrPatch(lst->next))) { CPrec_NewPointerPatch(¤t->next, addrPatch->value); - } else { - next = CPrec_AppendAlign(); - CPrec_NewPointerPatch(¤t->next, next); - current = next; - lst = lst->next; - CPrec_NewAddrPatch(lst, next); - goto restart; + break; } + + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + lst = lst->next; + CPrec_NewAddrPatch(lst, next); } return first; @@ -670,8 +927,7 @@ static TypeTemplDep *CPrec_GetTypeTemplDepPatch(TypeTemplDep *type) { CPrec_NewPointerPatch(&p->u.bitfield.size, CPrec_GetExpressionPatch(type->u.bitfield.size)); break; default: -#line 1295 - CError_FATAL(); + CError_FATAL(1295); } return p; @@ -817,7 +1073,7 @@ static ObjCMethodArg *CPrec_GetObjCMethodArgPatch(ObjCMethodArg *arg) { first = current = CPrec_AppendAlign(); do { - CPrec_AppendData(arg, sizeof(ObjCMethodArg)); + CPrec_AppendData(arg, sizeof(ObjCMethod)); if (arg->selector) CPrec_NamePatch(¤t->selector, arg->selector); if (arg->name) @@ -1087,8 +1343,7 @@ static TemplArg *CPrec_GetTemplateArgPatch(TemplArg *arg) { CPrec_NewPointerPatch(¤t->data.ttargtype, CPrec_GetTypePatch(arg->data.ttargtype)); break; default: -#line 1879 - CError_FATAL(); + CError_FATAL(1879); } if (!arg->next) @@ -1125,12 +1380,10 @@ static TemplParam *CPrec_GetTemplateParamPatch(TemplParam *param) { case TPT_TEMPLATE: if (param->data.templparam.plist) CPrec_NewPointerPatch(¤t->data.templparam.plist, CPrec_GetTemplateParamPatch(param->data.templparam.plist)); -#line 1953 - CError_ASSERT(!param->data.templparam.defaultarg); + CError_ASSERT(1953, !param->data.templparam.defaultarg); break; default: -#line 1958 - CError_FATAL(); + CError_FATAL(1958); } if (!param->next) @@ -1206,8 +1459,7 @@ static TStreamElement *CPrec_GetTStreamPatch(TStreamElement *tokens, SInt32 coun break; default: if (tokens->tokentype < 0) -#line 2063 - CError_FATAL(); + CError_FATAL(2063); } x++; tokens++; @@ -1361,8 +1613,7 @@ static TemplateAction *CPrec_GetTemplateActionPatch(TemplateAction *act) { CPrec_NewPointerPatch(¤t->u.refobj, CPrec_GetObjBasePatch(act->u.refobj)); break; default: -#line 2410 - CError_FATAL(); + CError_FATAL(2410); } if (!act->next) @@ -1549,8 +1800,7 @@ static Type *CPrec_GetTypePatch(Type *type) { case TYPEOBJCID: case TYPETEMPLDEPEXPR: default: -#line 2796 - CError_FATAL(); + CError_FATAL(2796); return NULL; } } @@ -1619,8 +1869,7 @@ repeat: case EAT_TERMINATE: break; default: -#line 2905 - CError_FATAL(); + CError_FATAL(2905); } if (exc->prev) { @@ -1652,17 +1901,247 @@ static ENodeList *CPrec_GetExpressionListPatch(ENodeList *lst) { return first; } -static void CPrec_GetEMemberInfoPatch() {} +static EMemberInfo *CPrec_GetEMemberInfoPatch(EMemberInfo *emember) { + EMemberInfo *p; + + CError_FATAL(2953); + + p = CPrec_AppendAlign(); + CPrec_AppendData(emember, sizeof(EMemberInfo)); + + if (emember->path) + CPrec_NewPointerPatch(&p->path, CPrec_GetClassAccessPatch(emember->path)); + if (emember->expr) + CPrec_NewPointerPatch(&p->expr, CPrec_GetExpressionPatch(emember->expr)); + CError_ASSERT(2968, !emember->templargs); + CPrec_NewPointerPatch(&p->list, CPrec_GetNameSpaceObjectListPatch(emember->list)); + + return p; +} + +static ENode *CPrec_GetExpressionPatch(ENode *expr) { + ENode *p; + + if (ENODE_IS(expr, ETEMPLDEP) && expr->data.templdep.subtype == TDE_SOURCEREF) + expr->data.templdep.u.sourceref.token = NULL; + + p = CPrec_AppendAlign(); + CPrec_AppendData(expr, sizeof(ENode)); + + CPrec_NewPointerPatch(&p->rtype, CPrec_GetTypePatch(expr->rtype)); + + switch (expr->type) { + ENODE_CASE_MONADIC: + CPrec_NewPointerPatch(&p->data.monadic, CPrec_GetExpressionPatch(expr->data.monadic)); + break; + ENODE_CASE_DIADIC_ALL: + CPrec_NewPointerPatch(&p->data.diadic.left, CPrec_GetExpressionPatch(expr->data.diadic.left)); + CPrec_NewPointerPatch(&p->data.diadic.right, CPrec_GetExpressionPatch(expr->data.diadic.right)); + break; + case ECOND: + CPrec_NewPointerPatch(&p->data.cond.cond, CPrec_GetExpressionPatch(expr->data.cond.cond)); + CPrec_NewPointerPatch(&p->data.cond.expr1, CPrec_GetExpressionPatch(expr->data.cond.expr1)); + CPrec_NewPointerPatch(&p->data.cond.expr2, CPrec_GetExpressionPatch(expr->data.cond.expr2)); + break; + case ESTRINGCONST: + CPrec_RawMemPatch(&p->data.string.data, expr->data.string.data, expr->data.string.size); + break; + case EOBJREF: + CPrec_NewPointerPatch(&p->data.objref, CPrec_GetObjectPatch(expr->data.objref)); + break; + case EOBJLIST: + CPrec_NewPointerPatch(&p->data.objlist.list, CPrec_GetNameSpaceObjectListPatch(expr->data.objlist.list)); + CError_ASSERT(3043, !expr->data.objlist.templargs); + if (expr->data.objlist.name) + CPrec_NamePatch(&p->data.objlist.name, expr->data.objlist.name); + break; + case EMFPOINTER: + CPrec_NewPointerPatch(&p->data.mfpointer.accessnode, CPrec_GetExpressionPatch(expr->data.mfpointer.accessnode)); + CPrec_NewPointerPatch(&p->data.mfpointer.mfpointer, CPrec_GetExpressionPatch(expr->data.mfpointer.mfpointer)); + break; + case ENULLCHECK: + CPrec_NewPointerPatch(&p->data.nullcheck.nullcheckexpr, CPrec_GetExpressionPatch(expr->data.nullcheck.nullcheckexpr)); + CPrec_NewPointerPatch(&p->data.nullcheck.condexpr, CPrec_GetExpressionPatch(expr->data.nullcheck.condexpr)); + break; + case ETEMP: + CPrec_NewPointerPatch(&p->data.temp.type, CPrec_GetTypePatch(expr->data.temp.type)); + break; + case EFUNCCALL: + case EFUNCCALLP: + CPrec_NewPointerPatch(&p->data.funccall.funcref, CPrec_GetExpressionPatch(expr->data.funccall.funcref)); + CPrec_NewPointerPatch(&p->data.funccall.functype, CPrec_GetTypePatch(TYPE(expr->data.funccall.functype))); + if (expr->data.funccall.args) + CPrec_NewPointerPatch(&p->data.funccall.args, CPrec_GetExpressionListPatch(expr->data.funccall.args)); + break; + case EMEMBER: + CPrec_NewPointerPatch(&p->data.emember, CPrec_GetEMemberInfoPatch(expr->data.emember)); + break; + case ETEMPLDEP: + switch (expr->data.templdep.subtype) { + case TDE_PARAM: + break; + case TDE_SIZEOF: + case TDE_ALIGNOF: + CPrec_NewPointerPatch(&p->data.templdep.u.typeexpr.type, CPrec_GetTypePatch(expr->data.templdep.u.typeexpr.type)); + break; + case TDE_CAST: + if (expr->data.templdep.u.cast.args) + CPrec_NewPointerPatch(&p->data.templdep.u.cast.args, CPrec_GetExpressionListPatch(expr->data.templdep.u.cast.args)); + CPrec_NewPointerPatch(&p->data.templdep.u.cast.type, CPrec_GetTypePatch(expr->data.templdep.u.cast.type)); + break; + case TDE_QUALNAME: + CPrec_NamePatch(&p->data.templdep.u.qual.name, expr->data.templdep.u.qual.name); + CPrec_NewPointerPatch(&p->data.templdep.u.qual.type, CPrec_GetTypePatch(TYPE(expr->data.templdep.u.qual.type))); + break; + case TDE_OBJ: + CPrec_NewPointerPatch(&p->data.templdep.u.obj, CPrec_GetObjectPatch(expr->data.templdep.u.obj)); + break; + case TDE_SOURCEREF: + CPrec_NewPointerPatch(&p->data.templdep.u.sourceref.expr, CPrec_GetExpressionPatch(expr->data.templdep.u.sourceref.expr)); + break; + case TDE_ADDRESS_OF: + CPrec_NewPointerPatch(&p->data.templdep.u.monadic, CPrec_GetExpressionPatch(expr->data.templdep.u.monadic)); + break; + default: + CError_FATAL(3136); + } + break; + case EINTCONST: + case EFLOATCONST: + case EPRECOMP: + case EARGOBJ: + case ELOCOBJ: + case ELABEL: + case EINSTRUCTION: + case EVECTOR128CONST: + break; + default: + CError_FATAL(3142); + } + + return p; +} + +static CI_Switch *CPrec_GetSwitchInfoPatch(CI_Switch *si) { + CI_Switch *p = CPrec_AppendAlign(); + CPrec_AppendData(si, sizeof(CI_Switch) + sizeof(CI_SwitchCase) * (si->numcases - 1)); + + CPrec_NewPointerPatch(&p->expr, CPrec_GetExpressionPatch(si->expr)); + CPrec_NewPointerPatch(&p->unkSwitch8, CPrec_GetTypePatch(si->unkSwitch8)); + return p; +} + +static InlineAsm *CPrec_GetInlineAsmPatch(InlineAsm *ia, SInt32 size) { + InlineAsm *p; + SInt32 index; + SInt32 offset; + Object *object; + + p = CPrec_AppendAlign(); + CPrec_AppendData(ia, size); + + index = 0; + while (1) { + object = InlineAsm_GetObjectOffset(ia, index, &offset); + if (!object) + break; + + object = CPrec_GetObjectPatch(object); + CPrec_NewPointerPatch((char *) p + offset, object); + index++; + } + + return p; +} + +static CI_Statement *CPrec_GetStatementPatch(CI_Statement *stmt, short count) { + short i; + CI_Statement *first, *current; + + for (i = 0; i < count; i++) { + stmt[i].sourcefilepath = NULL; + stmt[i].sourceoffset = -1; + } + + first = current = CPrec_AppendAlign(); + CPrec_AppendData(stmt, sizeof(CI_Statement) * count); + + for (i = 0; i < count; i++) { + if (stmt->dobjstack) + CPrec_NewPointerPatch(¤t->dobjstack, CPrec_GetExceptionPatch(stmt->dobjstack)); + + switch (stmt->type) { + case ST_EXPRESSION: + case ST_RETURN: + case ST_BEGINCATCH: + case ST_ENDCATCH: + case ST_ENDCATCHDTOR: + if (stmt->u.expr) + CPrec_NewPointerPatch(¤t->u.expr, CPrec_GetExpressionPatch(stmt->u.expr)); + break; + case ST_IFGOTO: + case ST_IFNGOTO: + CPrec_NewPointerPatch(¤t->u.ifgoto.expr, CPrec_GetExpressionPatch(stmt->u.ifgoto.expr)); + break; + case ST_SWITCH: + CPrec_NewPointerPatch(¤t->u.switchdata, CPrec_GetSwitchInfoPatch(stmt->u.switchdata)); + break; + case ST_ASM: + CPrec_NewPointerPatch(¤t->u.asmdata.data, CPrec_GetInlineAsmPatch(stmt->u.asmdata.data, stmt->u.asmdata.size)); + break; + case ST_NOP: + case ST_LABEL: + case ST_GOTO: + break; + default: + CError_FATAL(3261); + } + + current++; + stmt++; + } + + return first; +} + +static CI_Var *CPrec_GetLocObjectPatch(CI_Var *obj, short count) { + CI_Var *first, *current; + short i; -static ENode *CPrec_GetExpressionPatch(ENode *enode) { + first = current = CPrec_AppendAlign(); + CPrec_AppendData(obj, sizeof(CI_Var) * count); + + for (i = 0; i < count; i++) { + CPrec_NamePatch(¤t->name, obj->name); + CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch(obj->type)); + current++; + obj++; + } + return first; } -static void CPrec_GetSwitchInfoPatch() {} -static void CPrec_GetInlineAsmPatch() {} -static void CPrec_GetStatementPatch() {} -static void CPrec_GetLocObjectPatch() {} -static void CPrec_GetInlineFuncPatch() {} +static CI_FuncData *CPrec_GetInlineFuncPatch(CI_FuncData *ifunc) { + CI_FuncData *p; + + memclrw(&ifunc->fileoffset, sizeof(FileOffsetInfo)); + ifunc->symdecloffset = 0; + ifunc->functionbodyoffset = 0; + ifunc->functionbodypath = NULL; + ifunc->symdeclend = 0; + + p = CPrec_AppendAlign(); + CPrec_AppendData(ifunc, sizeof(CI_FuncData)); + + if (ifunc->numarguments) + CPrec_NewPointerPatch(&p->arguments, CPrec_GetLocObjectPatch(ifunc->arguments, ifunc->numarguments)); + if (ifunc->numlocals) + CPrec_NewPointerPatch(&p->locals, CPrec_GetLocObjectPatch(ifunc->locals, ifunc->numlocals)); + if (ifunc->numstatements) + CPrec_NewPointerPatch(&p->statements, CPrec_GetStatementPatch(ifunc->statements, ifunc->numstatements)); + + return p; +} static ObjEnumConst *CPrec_GetObjEnumConstPatch(ObjEnumConst *obj) { AddrPatch *addrPatch; @@ -1677,8 +2156,7 @@ static ObjEnumConst *CPrec_GetObjEnumConstPatch(ObjEnumConst *obj) { do { CPrec_AppendData(obj, sizeof(ObjEnumConst)); if (cprec_dowrite) { -#line 3349 - CError_ASSERT(obj->access != 255); + CError_ASSERT(3349, obj->access != 255); obj->access = 255; } CPrec_NamePatch(¤t->name, obj->name); @@ -1744,8 +2222,48 @@ static ObjNameSpace *CPrec_GetObjNameSpacePatch(ObjNameSpace *obj) { return p; } -static ObjMemberVar *CPrec_GetObjMemberVarPatch(ObjMemberVar *obj) { +static ObjMemberVar *CPrec_GetObjMemberVarPatch(ObjMemberVar *ivar) { + AddrPatch *addrPatch; + ObjMemberVar *first, *current, *next; + + if ((addrPatch = CPrec_FindAddrPatch(ivar))) + return addrPatch->value; + + first = current = CPrec_AppendAlign(); + CPrec_NewAddrPatch(ivar, first); + + while (1) { + if (ivar->has_path) { + CPrec_AppendData(ivar, sizeof(ObjMemberVarPath)); + if (OBJ_MEMBER_VAR_PATH(ivar)->path) + CPrec_NewPointerPatch( + &OBJ_MEMBER_VAR_PATH(current)->path, + CPrec_GetClassAccessPatch(OBJ_MEMBER_VAR_PATH(ivar)->path)); + } else { + CPrec_AppendData(ivar, sizeof(ObjMemberVar)); + } + if (ivar->name) + CPrec_NamePatch(¤t->name, ivar->name); + CPrec_NewPointerPatch(¤t->type, CPrec_GetTypePatch(ivar->type)); + + if (!ivar->next) + break; + + if ((addrPatch = CPrec_FindAddrPatch(ivar->next))) { + CPrec_NewPointerPatch(¤t->next, addrPatch->value); + break; + } + + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + + current = next; + ivar = ivar->next; + CPrec_NewAddrPatch(ivar, current); + } + + return first; } static DefArgCtorInfo *CPrec_GetDefArgCtorInfoPatch(DefArgCtorInfo *dac) { @@ -1775,15 +2293,102 @@ static InlineXRef *CPrec_GetInlineXRefPatch(InlineXRef *ix) { return first; } -static Object *CPrec_GetObjectPatch(Object *o) { +static Object *CPrec_GetObjectPatch(Object *obj) { + AddrPatch *addrPatch; + Object *p; + + if (CWUserBreak(cparams.context) != cwNoErr) + CError_UserBreak(); + + if ((addrPatch = CPrec_FindAddrPatch(obj))) + return addrPatch->value; + + p = CPrec_AppendAlign(); + CPrec_NewAddrPatch(obj, p); + + obj->toc = NULL; + + if ((obj->qual & Q_400000) && obj->datatype != DALIAS) { + CPrec_AppendData(obj, sizeof(ObjectTemplated)); + CPrec_NewPointerPatch(&OBJECT_TEMPL(p)->parent, CPrec_GetObjectPatch(OBJECT_TEMPL(obj)->parent)); + } else { + CPrec_AppendData(obj, sizeof(Object)); + } + + if (obj->nspace) + CPrec_NewPointerPatch(&p->nspace, CPrec_GetNameSpacePatch(obj->nspace)); + if (obj->name) + CPrec_NamePatch(&p->name, obj->name); + CPrec_NewPointerPatch(&p->type, CPrec_GetTypePatch(obj->type)); + + switch (obj->datatype) { + case DABSOLUTE: + break; + + case DLOCAL: + CError_FATAL(3580); + break; + + case DFUNC: + case DVFUNC: + if (IS_TEMPL_FUNC(obj->type)) + CPrec_NewPointerPatch(&p->u.func.u.templ, CPrec_GetTemplateFunctionPatch(obj->u.func.u.templ)); + else if ((obj->qual & Q_INLINE) && obj->u.func.u.ifuncdata) + CPrec_NewPointerPatch(&p->u.func.u.ifuncdata, CPrec_GetInlineFuncPatch(obj->u.func.u.ifuncdata)); + + if (obj->u.func.defargdata) + CPrec_NewPointerPatch(&p->u.func.defargdata, CPrec_GetDefArgCtorInfoPatch(obj->u.func.defargdata)); + if (obj->u.func.linkname) + CPrec_NamePatch(&p->u.func.linkname, obj->u.func.linkname); + if (obj->u.func.inst) + CPrec_NewPointerPatch(&p->u.func.inst, CPrec_GetTemplFuncInstancePatch(obj->u.func.inst)); + break; + + case DDATA: + CError_ASSERT(3622, !obj->u.data.info); + if (obj->qual & Q_10000) { + switch (obj->type->type) { + case TYPEINT: + case TYPEENUM: + case TYPEPOINTER: + break; + case TYPEFLOAT: + CPrec_RawMemPatch(&p->u.data.u.floatconst, obj->u.data.u.floatconst, sizeof(Float)); + break; + default: + CError_FATAL(3638); + } + } + if (obj->u.data.linkname) + CPrec_NamePatch(&p->u.data.linkname, obj->u.data.linkname); + break; + + case DINLINEFUNC: + CPrec_RawMemPatch(&p->u.ifunc.data, obj->u.ifunc.data, obj->u.ifunc.size); + if (obj->u.ifunc.xrefs) + CPrec_NewPointerPatch(&p->u.ifunc.xrefs, CPrec_GetInlineXRefPatch(obj->u.ifunc.xrefs)); + break; + + case DALIAS: + CPrec_NewPointerPatch(&p->u.alias.object, CPrec_GetObjectPatch(obj->u.alias.object)); + if (obj->u.alias.member) + CPrec_NewPointerPatch(&p->u.alias.member, CPrec_GetClassAccessPatch(obj->u.alias.member)); + break; + + default: + CError_FATAL(3677); + } + + if (cprec_dowrite) + obj->datatype = -1; + return p; } static ObjBase *CPrec_GetObjBasePatch(ObjBase *obj) { switch (obj->otype) { default: -#line 3694 - CError_FATAL(); + CError_FATAL(3694); case OT_ENUMCONST: return (ObjBase *) CPrec_GetObjEnumConstPatch((ObjEnumConst *) obj); case OT_TYPE: @@ -1945,16 +2550,217 @@ static NameSpace *CPrec_GetNameSpacePatch(NameSpace *nspace) { return p; } -static void CPrec_DumpRootNameSpace() {} -static void CPrec_GetSOMPatch() {} -static void CPrec_GetOLinkPatch() {} -static void CPrec_GetStaticDataPatch() {} -static void CPrec_GetCallbackPatch() {} -static void CPrec_GetSelHashTablePatch() {} -static void CPrec_GetIExpressionPatch() {} -static void CPrec_GetInlineActionPatch() {} +static void CPrec_DumpRootNameSpace(void) { + NameSpaceList *nslist; + NameSpaceName *nsname; + int i; + + CError_ASSERT(3905, cscope_root->is_hash); + + if (cscope_root->usings) { + nslist = CPrec_GetNameSpaceListPatch(cscope_root->usings); + if (cprec_dowrite) + cprec_header->usings = nslist; + } + + if (cprec_dowrite) + cprec_header->root_names = cscope_root->names; + + i = 0; + do { + if (cscope_root->data.hash[i]) { + nsname = CPrec_GetNameSpaceNamePatch(cscope_root->data.hash[i], 1); + if (cprec_dowrite) { + if (cprec_ioerror != noErr) + break; + cprec_header->root_nametable[i] = nsname; + } + } + } while (++i < 0x400); +} + +static CSOMStub *CPrec_GetSOMPatch(CSOMStub *stub) { + CSOMStub *first, *current, *next; + + first = current = CPrec_AppendAlign(); + while (1) { + CPrec_AppendData(stub, sizeof(CSOMStub)); + + CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(stub->object)); + CPrec_NewPointerPatch(¤t->tclass, CPrec_GetTypePatch(TYPE(stub->tclass))); + + if (!stub->next) + break; + + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + stub = stub->next; + } + + return first; +} + +static OLinkList *CPrec_GetOLinkPatch(OLinkList *olink) { + OLinkList *first, *current, *next; + + first = current = CPrec_AppendAlign(); + while (1) { + CPrec_AppendData(olink, sizeof(OLinkList)); + + CPrec_NewPointerPatch(¤t->obj, CPrec_GetObjectPatch(olink->obj)); + + if (!olink->next) + break; + + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + olink = olink->next; + } + + return first; +} + +static StaticData *CPrec_GetStaticDataPatch(StaticData *sd) { + StaticData *current, *first, *next; + + first = current = CPrec_AppendAlign(); + while (1) { + CPrec_AppendData(sd, sizeof(StaticData)); + + CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(sd->object)); + if (sd->buffer) + CPrec_RawMemPatch(¤t->buffer, sd->buffer, sd->object->type->size); + if (sd->links) + CPrec_NewPointerPatch(¤t->links, CPrec_GetOLinkPatch(sd->links)); + + if (!sd->next) + break; + + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + sd = sd->next; + } + + return first; +} + +static CallbackAction *CPrec_GetCallbackPatch(CallbackAction *ca) { + CallbackAction *first, *current, *next; + + first = current = CPrec_AppendAlign(); + while (1) { + CPrec_AppendData(ca, sizeof(CallbackAction)); + + CPrec_NewPointerPatch(¤t->obj, CPrec_GetObjectPatch(ca->obj)); + CPrec_NewPointerPatch(¤t->tclass, CPrec_GetTypePatch(TYPE(ca->tclass))); + + if (!ca->next) + break; + + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + ca = ca->next; + } + + return first; +} + +static ObjCSelector **CPrec_GetSelHashTablePatch(ObjCSelector **table) { + ObjCSelector **first, **current; + int i; + + first = current = CPrec_AppendAlign(); + CPrec_AppendData(table, sizeof(ObjCSelector *) * 0x400); + + for (i = 0; i < 0x400; i++) { + if (*table) + CPrec_NewPointerPatch(current, CPrec_GetObjCSelectorPatch(*table)); + table++; + current++; + } + + return first; +} + +static InitExpr *CPrec_GetIExpressionPatch(InitExpr *initexpr) { + InitExpr *first, *current, *next; + + first = current = CPrec_AppendAlign(); + while (1) { + CPrec_AppendData(initexpr, sizeof(InitExpr)); + + CPrec_NewPointerPatch(¤t->object, CPrec_GetObjectPatch(initexpr->object)); + CPrec_NewPointerPatch(¤t->expr, CPrec_GetExpressionPatch(initexpr->expr)); + + if (!initexpr->next) + break; + + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + initexpr = initexpr->next; + } + + return first; +} + +static CI_Action *CPrec_GetInlineActionPatch(CI_Action *act) { + CI_Action *current, *first, *next; + + first = current = CPrec_AppendAlign(); + while (1) { + if (act->actiontype == CI_ActionInlineFunc) + memclrw(&act->u.inlinefunc.fileoffset, sizeof(FileOffsetInfo)); + + CPrec_AppendData(act, sizeof(CI_Action)); + + CPrec_NewPointerPatch(¤t->obj, CPrec_GetObjectPatch(act->obj)); + + switch (act->actiontype) { + case CI_ActionInlineFunc: + if (act->u.inlinefunc.stream.firsttoken) + CPrec_NewPointerPatch( + ¤t->u.inlinefunc.stream.firsttoken, + CPrec_GetTStreamPatch(act->u.inlinefunc.stream.firsttoken, act->u.inlinefunc.stream.tokens)); + if (act->u.inlinefunc.tclass) + CPrec_NewPointerPatch(¤t->u.inlinefunc.tclass, CPrec_GetTypePatch(TYPE(act->u.inlinefunc.tclass))); + break; + + case CI_ActionMemberFunc: + CPrec_NewPointerPatch(¤t->u.memberfunc.templ, CPrec_GetTypePatch(TYPE(act->u.memberfunc.templ))); + CPrec_NewPointerPatch(¤t->u.memberfunc.inst, CPrec_GetTypePatch(TYPE(act->u.memberfunc.inst))); + CPrec_NewPointerPatch(¤t->u.memberfunc.tmemb, CPrec_GetTemplateMemberPatch(act->u.memberfunc.tmemb)); + break; + + case CI_ActionTemplateFunc: + CPrec_NewPointerPatch(¤t->u.templatefunc.func, CPrec_GetTemplateFunctionPatch(act->u.templatefunc.func)); + CPrec_NewPointerPatch(¤t->u.templatefunc.inst, CPrec_GetTemplFuncInstancePatch(act->u.templatefunc.inst)); + break; + + case CI_ActionDefaultFunc: + break; + + default: + CError_FATAL(4177); + } + + if (!act->next) + break; + + next = CPrec_AppendAlign(); + CPrec_NewPointerPatch(¤t->next, next); + current = next; + act = act->next; + } + + return first; +} -static void CPrec_GenerateBuiltinPatches() { +static void CPrec_GenerateBuiltinPatches(void) { int x; int y; Patch *scan; @@ -1975,7 +2781,7 @@ static void CPrec_GenerateBuiltinPatches() { CPrec_AppendWord32(0); } -static void CPrec_GenerateTokenStreamPatches() { +static void CPrec_GenerateTokenStreamPatches(void) { TokenPatch *scan; for (scan = cprec_tokenpatches; scan; scan = scan->next) { @@ -2032,7 +2838,7 @@ static OSErr CPrec_CompressWrite(const char *data, SInt32 size) { return noErr; } -static OSErr CPrec_FlushRawBuffer() { +static OSErr CPrec_FlushRawBuffer(void) { OSErr err; if (cprec_dowrite) { @@ -2049,7 +2855,7 @@ static OSErr CPrec_FlushRawBuffer() { } } -static OSErr CPrec_FlushBufferCheck() { +static OSErr CPrec_FlushBufferCheck(void) { static SInt32 flushmax; OSErr err; @@ -2067,7 +2873,7 @@ static OSErr CPrec_FlushBufferCheck() { return noErr; } -static int CPrec_CompressPatches() { +static int CPrec_CompressPatches(void) { Patch *scan; int count; SInt32 last; @@ -2078,8 +2884,7 @@ static int CPrec_CompressPatches() { last = 0; count = 0; while (scan) { -#line 4339 - CError_ASSERT((scan->offset & 0x80000001) == 0); + CError_ASSERT(4339, (scan->offset & 0x80000001) == 0); if ((scan->offset - last) >= -128 && (scan->offset - last) <= 126) CPrec_AppendByte(((scan->offset - last) >> 1) | 0x80); @@ -2094,7 +2899,146 @@ static int CPrec_CompressPatches() { return count; } -static void CPrec_DumpColorSymbolTable() {} +static OSErr CPrec_DumpColorSymbolTable(Boolean doWrite) { + OSErr err; + + freelheap(); + + CPrec_InitAddressHashTable(); + CPrec_InitPointerHashTable(); + + cprec_patch_list = NULL; + cprec_tokenpatches = NULL; + cprec_offset = 0; + cprec_zero_offset = 0; + cprec_dowrite = doWrite; + cprec_ioerror = noErr; + + CPrec_SetupBuiltIn(); + CPrec_AppendWord32(0); + + CPrec_DumpNameTable(); + if ((err = CPrec_FlushRawBuffer()) != noErr) + return err; + + CPrec_DumpMacroTable(); + if ((err = CPrec_FlushRawBuffer()) != noErr) + return err; + + CPrec_DumpRootNameSpace(); + if (doWrite) { + if (cprec_ioerror != noErr) + return cprec_ioerror; + if ((err = CPrec_FlushRawBuffer()) != noErr) + return err; + } + + if (ctempl_templates) { + TemplClass *p = TEMPL_CLASS(CPrec_GetTypePatch(TYPE(ctempl_templates))); + if (doWrite) + cprec_header->ctempl_templates = p; + if ((err = CPrec_FlushRawBuffer()) != noErr) + return err; + } + + if (ctempl_templatefuncs) { + TemplateFunction *p = CPrec_GetTemplateFunctionPatch(ctempl_templatefuncs); + if (doWrite) + cprec_header->ctempl_templatefuncs = p; + if ((err = CPrec_FlushRawBuffer()) != noErr) + return err; + } + + if (csom_stubs) { + CSOMStub *p = CPrec_GetSOMPatch(csom_stubs); + if (doWrite) + cprec_header->csom_stubs = p; + if ((err = CPrec_FlushRawBuffer()) != noErr) + return err; + } + + if (cprec_staticdata) { + StaticData *p = CPrec_GetStaticDataPatch(cprec_staticdata); + if (doWrite) + cprec_header->cprec_staticdata = p; + if ((err = CPrec_FlushRawBuffer()) != noErr) + return err; + } + + if (callbackactions) { + CallbackAction *p = CPrec_GetCallbackPatch(callbackactions); + if (doWrite) + cprec_header->callbackactions = p; + if ((err = CPrec_FlushRawBuffer()) != noErr) + return err; + } + + if (cobjc_type_class) { + Type *p = CPrec_GetTypePatch(cobjc_type_class); + if (doWrite) + cprec_header->cobjc_type_class = p; + if ((err = CPrec_FlushRawBuffer()) != noErr) + return err; + } + + if (cobjc_type_id) { + Type *p = CPrec_GetTypePatch(cobjc_type_id); + if (doWrite) + cprec_header->cobjc_type_id = p; + if ((err = CPrec_FlushRawBuffer()) != noErr) + return err; + } + + if (cobjc_type_sel) { + Type *p = CPrec_GetTypePatch(cobjc_type_sel); + if (doWrite) + cprec_header->cobjc_type_sel = p; + if ((err = CPrec_FlushRawBuffer()) != noErr) + return err; + } + + if (cobjc_selhashtable) { + ObjCSelector **p = CPrec_GetSelHashTablePatch(cobjc_selhashtable); + if (doWrite) + cprec_header->cobjc_selhashtable = p; + if ((err = CPrec_FlushRawBuffer()) != noErr) + return err; + } + + if (cobjc_classdefs) { + BClassList *p = CPrec_GetBClassListPatch(cobjc_classdefs); + if (doWrite) + cprec_header->cobjc_classdefs = p; + if ((err = CPrec_FlushRawBuffer()) != noErr) + return err; + } + + if (cobjc_protocols) { + ObjCProtocol *p = CPrec_GetObjCProtocolPatch(cobjc_protocols); + if (doWrite) + cprec_header->cobjc_protocols = p; + if ((err = CPrec_FlushRawBuffer()) != noErr) + return err; + } + + if (init_expressions) { + InitExpr *p = CPrec_GetIExpressionPatch(init_expressions); + if (doWrite) + cprec_header->init_expressions = p; + if ((err = CPrec_FlushRawBuffer()) != noErr) + return err; + } + + if (cinline_tactionlist) { + CI_Action *p = CPrec_GetInlineActionPatch(cinline_tactionlist); + if (doWrite) + cprec_header->cinline_tactionlist = p; + if ((err = CPrec_FlushRawBuffer()) != noErr) + return err; + } + + return noErr; +} static OSErr CPrec_FileAlign(short refnum, SInt32 *len) { OSErr err; @@ -2112,21 +3056,341 @@ static OSErr CPrec_FileAlign(short refnum, SInt32 *len) { return err; } -static void CPrec_WriteFile() {} +static OSErr CPrec_WriteFile(void) { + char str[128]; + int i; + HashNameNode *name; + OSErr err; + SInt32 offset; + + if (InitGList(&cprec_glist, 0x40000)) + CError_NoMem(); + + CompilerGetCString(10, str); + CWShowStatus(cparams.context, str, ""); + CPrep_RemoveSpecialMacros(); + + for (i = 0; i < 0x800; i++) { + for (name = name_hash_nodes[i]; name; name = name->next) + name->id = 0; + } + + if ((err = CPrec_DumpColorSymbolTable(0)) != noErr) + return err; + + CompilerGetCString(11, str); + CWShowStatus(cparams.context, str, ""); + + cprec_header = galloc(sizeof(Header)); + memclrw(cprec_header, sizeof(Header)); + + cprec_header->magic = 0xBEEFFACE; + cprec_header->version = 1047; + cprec_header->target = 2; + cprec_header->check_header_flags = copts.check_header_flags; + cprec_header->cplusplus = copts.cplusplus; + cprec_header->uniqueID = CParser_GetUniqueID(); + cprec_header->cobjc_selrefcount = cobjc_selrefcount; + cprec_header->cobjc_classrefcount = cobjc_classrefcount; + cprec_header->cobjc_stringcount = cobjc_stringcount; + + if ((err = COS_FileWrite(cprec_refnum, cprec_header, sizeof(Header))) != noErr) + return err; + + offset = sizeof(Header); + + if ((err = CPrec_DumpColorSymbolTable(1)) != noErr) + return err; + + cprec_header->x28 = cprec_offset; + cprec_header->x30 = offset; + + if ((err = COS_FileGetPos(cprec_refnum, &offset)) != noErr) + return err; + + cprec_header->x2C = offset - cprec_header->x30; + + cprec_header->compressedPatchCount = CPrec_CompressPatches(); + cprec_header->compressedPatchSize = cprec_glist.size; + cprec_header->compressedPatchOffset = offset; + + if (cprec_header->compressedPatchCount) { + if ((err = COS_FileWrite(cprec_refnum, *cprec_glist.data, cprec_glist.size)) != noErr) + return err; + offset += cprec_glist.size; + } + + if ((err = CPrec_FileAlign(cprec_refnum, &offset)) != noErr) + return err; + + cprec_glist.size = 0; + CPrec_GenerateBuiltinPatches(); + cprec_header->builtinPatchSize = cprec_glist.size; + cprec_header->builtinPatchOffset = offset; + + if ((err = COS_FileWrite(cprec_refnum, *cprec_glist.data, cprec_glist.size)) != noErr) + return err; + offset += cprec_glist.size; + + if (cprec_tokenpatches) { + cprec_glist.size = 0; + CPrec_GenerateTokenStreamPatches(); + cprec_header->tokenStreamPatchSize = cprec_glist.size; + cprec_header->tokenStreamPatchOffset = offset; + + if ((err = COS_FileWrite(cprec_refnum, *cprec_glist.data, cprec_glist.size)) != noErr) + return err; + offset += cprec_glist.size; + } + + if ((err = COS_FileSetPos(cprec_refnum, 0)) != noErr) + return err; + + if ((err = COS_FileWrite(cprec_refnum, cprec_header, sizeof(Header))) != noErr) + return err; + + return noErr; +} + +void PrecompilerWrite(void) { + OSErr err; + short strindex; + char str[128]; + FSSpec spec; + + spec = cparamblkptr->mainFileSpec; + if (CWGetPrecompiledHeaderSpec(cparamblkptr->context, &spec, precomp_target_str) == cwNoErr) { + strindex = 3; + err = COS_FileNew(&spec, &cprec_refnum, copts.pchCreator, copts.pchType); + if (err == noErr) { + strindex = 4; + err = CPrec_WriteFile(); + } + CleanupPrecompiler(); + + if (err != noErr) { + CompilerGetCString(strindex, str); + sprintf(string, str, err); + CWReportMessage(cparamblkptr->context, NULL, string, NULL, messagetypeError, 0); + } else { + CWFileTime time = 0; + CWSetModDate(cparamblkptr->context, &spec, &time, 1); + } + } +} + +static void CPrec_ReadData(SInt32 offset, void *buffer, SInt32 size) { + if ( + COS_FileSetPos(cprec_refnum, offset) != noErr || + COS_FileRead(cprec_refnum, buffer, size) != noErr + ) + CError_ErrorTerm(CErrorStr181); +} + +static void CPrec_ReadRawBuffer(void) { + UInt8 *buffer; + UInt8 *work; + UInt8 *end; + UInt32 size; + int ch; + + if (!cprec_buffer) { + size = cprec_header->x28 + (cprec_header->x28 >> 7) + 64; + buffer = galloc(size); + cprec_rawbuffer = buffer; + + work = buffer + size - cprec_header->x2C; + CPrec_ReadData(cprec_header->x30, work, cprec_header->x2C); + } else { + buffer = galloc(cprec_header->x28); + cprec_rawbuffer = buffer; + work = (UInt8 *) cprec_buffer + cprec_header->x30; + } + + end = work + cprec_header->x2C; + + while (work < end) { + if ((ch = *(work++)) >= 0xE0) { + ch -= 0xE0; + do { + *(buffer++) = 0; + } while (--ch >= 0); + } else { + do { + *(buffer++) = *(work++); + } while (--ch >= 0); + } + } + + if (work != end || buffer != RESOLVE_RAW_BUFFER(cprec_header->x28)) + CError_ErrorTerm(CErrorStr181); +} + +static void CPrec_RelocateRawBuffer(void) { + UInt8 *patches; + UInt32 offset; + UInt8 *dest; + SInt32 count; + UInt8 *patch; + UInt32 var; + + if ((count = cprec_header->compressedPatchCount)) { + if (!cprec_buffer) { + patches = lalloc(cprec_header->compressedPatchSize); + CPrec_ReadData(cprec_header->compressedPatchOffset, patches, cprec_header->compressedPatchSize); + } else { + patches = RESOLVE_BUFFER(cprec_header->compressedPatchOffset); + } + + offset = 0; + patch = patches; + dest = cprec_rawbuffer; + do { + if (!(*patch & 0x80)) { + ((UInt8 *) &var)[0] = *(patch++); + ((UInt8 *) &var)[1] = *(patch++); + ((UInt8 *) &var)[2] = *(patch++); + ((UInt8 *) &var)[3] = *(patch++); + offset = var; + } else { + offset += (char) (*(patch++) * 2); + } + *((uintptr_t *) (dest + offset)) += (uintptr_t) dest; + } while (--count > 0); + + freelheap(); + + if (patch != (patches + cprec_header->compressedPatchSize)) + CError_ErrorTerm(CErrorStr181); + } +} + +static void CPrec_RelocateBuiltins(void) { + UInt32 *patches; + void *builtin; + UInt32 count; + UInt8 *buffer; + + if (cprec_header->builtinPatchSize) { + CPrec_SetupBuiltInArray(); + if (!cprec_buffer) { + patches = lalloc(cprec_header->builtinPatchSize); + CPrec_ReadData(cprec_header->builtinPatchOffset, patches, cprec_header->builtinPatchSize); + } else { + patches = RESOLVE_BUFFER(cprec_header->builtinPatchOffset); + } -void PrecompilerWrite() { + buffer = cprec_rawbuffer; + while (1) { + if (!(count = *(patches++))) + break; + + builtin = cprec_builtin_array[*(patches++)]; + do { + *((void **) (buffer + *(patches++))) = builtin; + } while (--count); + } + } } -static void CPrec_ReadData() {} -static void CPrec_ReadRawBuffer() {} -static void CPrec_RelocateRawBuffer() {} -static void CPrec_RelocateBuiltins() {} -static void CPrec_RelocateTokenStreams() {} -static void CPrec_RelocateMacroTable() {} -static void CPrec_RelocateTable() {} -static void CPrec_RelocateRootNameSpace() {} +static void CPrec_RelocateTokenStreams(void) { + UInt32 *patches; + UInt32 count; + TStreamElement *tokens; + UInt8 *buffer; + CPrepFileInfo *file; + SInt32 pos; + + if (cprec_header->tokenStreamPatchSize) { + CPrep_GetPrepPos(&file, &pos); + + if (!cprec_buffer) { + patches = lalloc(cprec_header->tokenStreamPatchSize); + CPrec_ReadData(cprec_header->tokenStreamPatchOffset, patches, cprec_header->tokenStreamPatchSize); + } else { + patches = RESOLVE_BUFFER(cprec_header->tokenStreamPatchOffset); + } -static void CPrec_FixNameIds() { + buffer = cprec_rawbuffer; + while (1) { + if (!*patches) + break; + + tokens = (TStreamElement *) (buffer + *(patches++)); + count = *(patches++); + + while (count--) { + tokens->tokenfile = file; + tokens->tokenoffset = pos; + tokens++; + } + } + } +} + +static void CPrec_RelocateMacroTable(void) { + int i; + int j; + int count; + UInt8 *buffer; + Macro **prec_table; + Macro **table; + Macro *macro; + uintptr_t offset; + + buffer = cprec_rawbuffer; + prec_table = cprec_header->macrotable; + table = macrohashtable; + + i = 0; + do { + for (macro = *table; macro; macro = macro->next) { + macro->name = GetHashNameNodeExport(macro->name->name); + count = macro->xC & 0x7FFF; + for (j = 1; j < count; j++) + macro->names[j - 1] = GetHashNameNodeExport(macro->names[j - 1]->name); + } + + if ((offset = (uintptr_t) *prec_table)) { + if (*table) { + macro = (Macro *) (buffer + offset); + while (macro->next) + macro = macro->next; + macro->next = *table; + } + *table = (Macro *) (buffer + offset); + } + + prec_table++; + table++; + } while (++i < 0x800); +} + +static void CPrec_RelocateTable(void **table, int size, void **dest) { + int i; + void *buffer = cprec_rawbuffer; + + for (i = 0; i < size; i++) { + if (*table) + *dest = (char *) buffer + (uintptr_t) *table; + else + *dest = NULL; + table++; + dest++; + } +} + +static void CPrec_RelocateRootNameSpace(void) { + CError_ASSERT(4981, cscope_root->is_hash); + + cscope_root->names = cprec_header->root_names; + CPrec_RelocateTable( + (void **) cprec_header->root_nametable, + 0x400, + (void **) cscope_root->data.hash); +} + +static void CPrec_FixNameIds(void) { int i; HashNameNode *node; @@ -2136,7 +3400,83 @@ static void CPrec_FixNameIds() { } } -static void CPrec_DefineStaticData() {} +static void CPrec_DefineStaticData(void) { + StaticData *sd = cprec_staticdata; + cprec_staticdata = NULL; + + while (sd) { + CInit_DeclareData(sd->object, sd->buffer, sd->links, sd->size); + sd = sd->next; + } +} void PrecompilerRead(short refnum, void *buffer) { + cprec_refnum = refnum; + cprec_buffer = buffer; + + CPrep_RemoveSpecialMacros(); + + if (!CScope_IsEmptySymTable()) + CError_ErrorTerm(CErrorStr180); + + if (!cprec_buffer) { + cprec_header = galloc(sizeof(Header)); + CPrec_ReadData(0, cprec_header, sizeof(Header)); + } else { + cprec_header = cprec_buffer; + } + + if (cprec_header->magic != 0xBEEFFACE) + CError_ErrorTerm(CErrorStr181); + if (cprec_header->version != 1047) + CError_ErrorTerm(CErrorStr222); + if (cprec_header->target != 2) + CError_ErrorTerm(CErrorStr223); + + copts.check_header_flags = cprec_header->check_header_flags; + + CPrec_ReadRawBuffer(); + CPrec_RelocateRawBuffer(); + CPrec_RelocateBuiltins(); + CPrec_RelocateTable((void **) cprec_header->nametable, 0x800, (void **) name_hash_nodes); + CPrec_FixNameIds(); + CPrec_RelocateMacroTable(); + CPrec_RelocateTokenStreams(); + CPrec_RelocateRootNameSpace(); + + if (!cprec_header->usings) + cscope_root->usings = NULL; + else + cscope_root->usings = RESOLVE_RAW_BUFFER(cprec_header->usings); + + ctempl_templates = RESOLVE_SAFE(cprec_header->ctempl_templates); + ctempl_templatefuncs = RESOLVE_SAFE(cprec_header->ctempl_templatefuncs); + csom_stubs = RESOLVE_SAFE(cprec_header->csom_stubs); + cprec_staticdata = RESOLVE_SAFE(cprec_header->cprec_staticdata); + callbackactions = RESOLVE_SAFE(cprec_header->callbackactions); + cobjc_type_class = RESOLVE_SAFE(cprec_header->cobjc_type_class); + cobjc_type_id = RESOLVE_SAFE(cprec_header->cobjc_type_id); + cobjc_type_sel = RESOLVE_SAFE(cprec_header->cobjc_type_sel); + cobjc_selhashtable = RESOLVE_SAFE(cprec_header->cobjc_selhashtable); + cobjc_classdefs = RESOLVE_SAFE(cprec_header->cobjc_classdefs); + cobjc_protocols = RESOLVE_SAFE(cprec_header->cobjc_protocols); + init_expressions = RESOLVE_SAFE(cprec_header->init_expressions); + cinline_tactionlist = RESOLVE_SAFE(cprec_header->cinline_tactionlist); + CParser_SetUniqueID(cprec_header->uniqueID); + cobjc_selrefcount = cprec_header->cobjc_selrefcount; + cobjc_classrefcount = cprec_header->cobjc_classrefcount; + cobjc_stringcount = cprec_header->cobjc_stringcount; + + cprec_refnum = 0; + + CleanupPrecompiler(); + cscope_current = cscope_root; + + if (!CParser_ReInitRuntimeObjects(1)) + CError_ErrorTerm(CErrorStr181); + + CPrep_InsertSpecialMacros(); + + if (cparamblkptr->isPrecompiling != 1) + CPrec_DefineStaticData(); } diff --git a/compiler_and_linker/unsorted/CodeGen.c b/compiler_and_linker/unsorted/CodeGen.c index 7b73bee..8268736 100644 --- a/compiler_and_linker/unsorted/CodeGen.c +++ b/compiler_and_linker/unsorted/CodeGen.c @@ -7,57 +7,40 @@ #include "compiler/CInt64.h" #include "compiler/CMachine.h" #include "compiler/CMangler.h" +#include "compiler/COptimizer.h" #include "compiler/CParser.h" #include "compiler/CPrep.h" #include "compiler/CPrepTokenizer.h" +#include "compiler/Coloring.h" +#include "compiler/CompilerTools.h" +#include "compiler/uDump.h" +#include "compiler/Exceptions.h" +#include "compiler/InlineAsmPPC.h" +#include "compiler/Intrinsics.h" #include "compiler/InstrSelection.h" +#include "compiler/GlobalOptimizer.h" +#include "compiler/ObjGenMachO.h" #include "compiler/Operands.h" #include "compiler/PCode.h" +#include "compiler/PCodeAssembly.h" #include "compiler/PCodeInfo.h" +#include "compiler/PCodeListing.h" #include "compiler/PCodeUtilities.h" +#include "compiler/Peephole.h" +#include "compiler/PPCError.h" #include "compiler/RegisterInfo.h" +#include "compiler/Scheduler.h" #include "compiler/StackFrame.h" +#include "compiler/Switch.h" #include "compiler/TOC.h" -#include "compiler/CompilerTools.h" +#include "compiler/ValueNumbering.h" #include "compiler/enode.h" +#include "compiler/objc.h" #include "compiler/objects.h" #include "compiler/scopes.h" #include "compiler/tokens.h" #include "compiler/types.h" -// TODO: MOVE ME -extern void Intrinsics_SetupRuntimeObjects(void); -extern void Intrinsics_ReInitRuntimeObjects(Boolean); -extern Boolean Intrinsics_IsPublicRuntimeObject(Object *); -extern ENode *Intrinsics_HandleIntrinsicCall(Object *func, ENodeList *arg_exprs); -extern void PPCError_Error(int, ...); -extern void PPCError_Warning(int, ...); -extern void PPCError_Message(char *, ...); -extern void globallyoptimizepcode(Object *); -extern void pclistblocks(char *, char *); -extern void pclistblocks_start_scheduler(char *, char *); -extern void pclistblocks_end_scheduler(); -extern void scheduleinstructions(Boolean); -extern void peepholemergeblocks(Object *, Boolean); -extern void peepholeoptimizeforward(Object *); -extern void peepholeoptimizepcode(Object *); -extern void colorinstructions(Object *); -extern void removecommonsubexpressions(Object *, Boolean); -extern int removedcommonsubexpressions; -extern SInt32 assemblefunction(Object *, void *); -extern void dumpswitchtables(Object *); -extern void ObjGen_DeclareInitFunction(Object *); -extern void *switchtables; -extern void initializeexceptiontables(); -extern void dumpexceptiontables(Object *, SInt32); -extern void switchstatement(ENode *, CLabel *); -extern void DumpIR(Statement **, Object *); -extern void InlineAsm_TranslateIRtoPCode(Statement *stmt); -typedef struct WeirdInlineAsmThing { - UInt8 x0, x1, x2; -} WeirdInlineAsmThing; -extern Statement **COpt_Optimizer(Object *, Statement **); - static Macro powcM; static Macro __powcM; static Macro ppc_cpu; @@ -876,7 +859,7 @@ static void callprofiler(char *name) { static void exitprofiler(void) { } -void CodeGen_Generator(Statement **statements, Object *func, UInt8 mysteryFlag, Boolean callOnModuleBind) { +void CodeGen_Generator(Statement *statements, Object *func, UInt8 mysteryFlag, Boolean callOnModuleBind) { Statement *stmt; Boolean has_varargs; PCodeBlock *tmp; @@ -924,7 +907,7 @@ void CodeGen_Generator(Statement **statements, Object *func, UInt8 mysteryFlag, resetTOCvarinfo(); init_registers(); - expandTOCreferences(statements); + expandTOCreferences(&statements->next); if (copts.debuglisting) DumpIR(statements, func); @@ -953,10 +936,10 @@ void CodeGen_Generator(Statement **statements, Object *func, UInt8 mysteryFlag, if (copts.profile) callprofiler(CMangler_GetLinkName(func)->name); - assign_labels(*statements); + assign_labels(statements->next); open_temp_registers(); - for (stmt = *statements; stmt; stmt = stmt->next) { + for (stmt = statements->next; stmt; stmt = stmt->next) { current_statement = stmt; current_linenumber = stmt->sourceoffset; switch (stmt->type) { @@ -991,7 +974,7 @@ void CodeGen_Generator(Statement **statements, Object *func, UInt8 mysteryFlag, break; case ST_SWITCH: newstatement(stmt->sourceoffset, stmt->value, (stmt->flags & StmtFlag_10) != 0); - switchstatement(stmt->expr, stmt->label); + switchstatement(stmt->expr, (SwitchInfo *) stmt->label); break; case ST_BEGINCATCH: capturestackpointer(stmt->expr->data.objref); @@ -1010,8 +993,7 @@ void CodeGen_Generator(Statement **statements, Object *func, UInt8 mysteryFlag, break; case ST_ASM: if (stmt->expr) { - // ... will need to understand inline ASM properly for this ... - if (((WeirdInlineAsmThing *) stmt->expr)->x2 & 1) { + if (((InlineAsm *) stmt->expr)->flags & IAFlag1) { CError_FATAL(2076); } else { branch_label(makepclabel()); @@ -1911,19 +1893,69 @@ void CodeGen_UpdateBackEndOptions(void) { } SInt32 CodeGen_objc_method_self_offset(ObjCMethod *meth) { - // TODO objc + SInt32 size; + + if (!meth->return_type) { + size = 4; + } else if ( + IS_TYPE_ARRAY(meth->return_type) || + IS_TYPE_NONVECTOR_STRUCT(meth->return_type) || + IS_TYPE_CLASS(meth->return_type) || + IS_TYPE_12BYTES_MEMBERPOINTER(meth->return_type) + ) + { + size = 8; + } else { + size = meth->return_type->size; + } + + if (size == 0) + size = 1; + + return (size + 3) & ~3; } SInt32 CodeGen_objc_method_sel_offset(ObjCMethod *meth) { - // TODO objc + return (CodeGen_objc_method_self_offset(meth) + 7) & ~3; } SInt32 CodeGen_objc_method_arg_offset(ObjCMethod *meth, ObjCMethodArg *arg) { - // TODO objc + SInt32 pos; + ObjCMethodArg *scan; + + pos = CodeGen_objc_method_sel_offset(meth) + 4; + for (scan = meth->selector_args; scan; scan = scan->next) { + if (scan == arg) + return pos; + + if (scan->type == NULL) + pos += 4; + else + pos += scan->type->size; + + pos = (pos + 3) & ~3; + } + + return 0; } SInt32 CodeGen_objc_method_args_size(ObjCMethod *meth) { - // TODO objc + SInt32 size; + ObjCMethodArg *scan; + + size = CodeGen_objc_method_self_offset(meth); + for (scan = meth->selector_args; scan; scan = scan->next) { + if (scan->next == NULL && scan->type == NULL) + return size; + + size = (size + 3) & ~3; + if (scan->type == NULL) + size += 4; + else + size += scan->type->size; + } + + return size; } ENode *CodeGen_HandleIntrinsicCall(Object *func, ENodeList *arg_exprs) { @@ -1959,11 +1991,16 @@ ENode *CodeGen_HandleTypeCast(ENode *expr, Type *type, UInt32 qual) { return NULL; } -short CodeGen_AssignCheck(ENode *expr, Type *type, Boolean flag1, Boolean flag2) { +short CodeGen_AssignCheck(const ENode *expr, const Type *type, Boolean flag1, Boolean flag2) { short result; - Type *exprtype = expr->rtype; - - if (copts.altivec_model && IS_TYPE_VECTOR(type) && IS_TYPE_VECTOR(exprtype) && TYPE_STRUCT(type)->stype == TYPE_STRUCT(exprtype)->stype) + const Type *exprtype = expr->rtype; + + if ( + copts.altivec_model && + IS_TYPE_VECTOR(type) && + IS_TYPE_VECTOR(exprtype) && + TYPE_STRUCT(type)->stype == TYPE_STRUCT(exprtype)->stype + ) result = CheckResult3; else result = CheckResult0; diff --git a/compiler_and_linker/unsorted/CodeGenOptPPC.c b/compiler_and_linker/unsorted/CodeGenOptPPC.c index 5723395..4964435 100644 --- a/compiler_and_linker/unsorted/CodeGenOptPPC.c +++ b/compiler_and_linker/unsorted/CodeGenOptPPC.c @@ -1,17 +1,120 @@ #include "compiler/CodeGenOptPPC.h" #include "compiler/InstrSelection.h" +#include "compiler/CCompiler.h" +#include "pref_structs.h" +#include "compiler/CParser.h" + +static short pref_versions; void CodeGen_InitCompiler(void) { init_cgdispatch(); } void CodeGen_TermCompiler(void) { - + // empty! } void CodeGen_InitBackEndOptions(void) { - // TODO + Handle handle; + PBackEnd pb; + PMachOLinker pmol; + + CWSecretGetNamedPreferences(cparams.context, "PPC CodeGen Mach-O", &handle); + pb = *((PBackEnd *) *handle); + pref_versions = pb.version; + + CWSecretGetNamedPreferences(cparams.context, "PPC Mach-O Linker", &handle); + pmol = *((PMachOLinker *) *handle); + + copts.code_alignment = 16; + copts.misaligned_mem_access = 1; + copts.switch_tables = 1; + copts.prepare_compress = 0; + copts.some_alignment = 4; + copts.altivec_model = 0; + copts.altivec_vrsave = 1; + copts.codegen_pic = pb.pic; + copts.codegen_dynamic = pb.dynamic; + if (!copts.codegen_dynamic) + copts.codegen_pic = 0; + copts.no_common = !pb.common; + copts.no_implicit_templates = 0; + copts.absolutepath = pmol.symfullpath; + copts.x06 = pmol.exports; + copts.schedule_mode = 2; + copts.altivec_model = pb.altivec; + copts.readonly_strings = pb.readonlystrings; + if (pb.schedule) + copts.schedule_mode = 2; + else + copts.schedule_mode = 0; + + switch (pb.processor) { + case 1: + copts.cpu = CPU_PPC601; + copts.schedule_cpu = 1; + break; + case 2: + copts.cpu = CPU_PPC603; + copts.schedule_cpu = 2; + break; + case 3: + copts.cpu = CPU_PPC603e; + copts.schedule_cpu = 5; + break; + case 4: + copts.cpu = CPU_PPC604; + copts.schedule_cpu = 3; + break; + case 5: + copts.cpu = CPU_PPC604e; + copts.schedule_cpu = 6; + break; + case 6: + copts.cpu = CPU_PPC750; + copts.schedule_cpu = 4; + break; + case 7: + copts.cpu = CPU_PPC7400; + copts.schedule_cpu = 7; + break; + case 8: + copts.cpu = CPU_PPC7450; + copts.schedule_cpu = 10; + break; + default: + copts.cpu = CPU_Generic; + copts.schedule_cpu = 8; + break; + } + + copts.peephole = pb.peephole; + copts.align_mode = pb.structalignment; + copts.profile = pb.profiler; + copts.fp_contract = pb.fpcontract; + copts.traceback = pb.tracebacktables > 0; + copts.x1D = pb.tracebacktables == 2; + copts.x1E = 0; + if (pb.processorspecific && copts.cpu >= CPU_PPC603) + copts.gen_fsel = 10; + else + copts.gen_fsel = 0; + if (pb.vrsave) + copts.altivec_vrsave = 1; + else + copts.altivec_vrsave = 0; + copts.ppc_unroll_speculative = 1; + copts.ppc_unroll_instructions_limit = 70; + copts.ppc_unroll_factor_limit = 10; + copts.ppc_opt_bclr_bcctr = 1; + copts.use_lmw_stmw = 1; + if (copts.optimizationlevel > 2) + copts.optimizewithasm = 1; + else + copts.optimizewithasm = 0; + copts.opt_strength_reduction_strict = 1; } void Test_Version_Numbers(void) { + // empty! } diff --git a/compiler_and_linker/unsorted/Exceptions.c b/compiler_and_linker/unsorted/Exceptions.c index 80d0cc4..cd25577 100644 --- a/compiler_and_linker/unsorted/Exceptions.c +++ b/compiler_and_linker/unsorted/Exceptions.c @@ -553,7 +553,7 @@ static UInt32 findPC_long(PCode *instr) { return pc; } -static void initializeexceptiontables(void) { +void initializeexceptiontables(void) { int i; for (i = 0; i < EAT_NACTIONS; i++) @@ -737,7 +737,7 @@ void recordexceptionactions(PCode *instr, ExceptionAction *actions) { } } -void deleteexceptionaction(PCAction *pca) { +static void deleteexceptionaction(PCAction *pca) { if (pca->prev) pca->prev->next = pca->next; else diff --git a/compiler_and_linker/unsorted/FuncLevelAsmPPC.c b/compiler_and_linker/unsorted/FuncLevelAsmPPC.c index a1ea8cc..e7fe347 100644 --- a/compiler_and_linker/unsorted/FuncLevelAsmPPC.c +++ b/compiler_and_linker/unsorted/FuncLevelAsmPPC.c @@ -119,7 +119,7 @@ static void FuncAsm_PreScanDirectives(void) { cprep_eoltokens = 1; if (setjmp(InlineAsm_assemblererror) == 0) { - while (tk == TK_IDENTIFIER && (directive = InlineAsm_IsDirective(1))) { + while (tk == TK_IDENTIFIER && (directive = InlineAsm_IsDirective(AssemblerType_0))) { InlineAsm_ProcessDirective(directive); if (tk == ';' || tk == TK_NEG7) { diff --git a/compiler_and_linker/unsorted/GCCInlineAsm.c b/compiler_and_linker/unsorted/GCCInlineAsm.c index 9bceb19..d0ae953 100644 --- a/compiler_and_linker/unsorted/GCCInlineAsm.c +++ b/compiler_and_linker/unsorted/GCCInlineAsm.c @@ -1,33 +1,230 @@ #include "compiler/GCCInlineAsm.h" +#include "compiler/CError.h" +#include "compiler/CExpr.h" +#include "compiler/CFunc.h" +#include "compiler/CInt64.h" +#include "compiler/CParser.h" +#include "compiler/CPrep.h" +#include "compiler/CPrepTokenizer.h" +#include "compiler/InlineAsm.h" +#include "compiler/objects.h" Statement *first_ST_ASM; +IALookupResult gcc_name_list[20]; +int gcc_name_list_index; -void InlineAsm_SkipComment() { +void InlineAsm_SkipComment(void) { + while (1) { + if (tk != '/') + break; + if (lookahead() != '*') + break; + + tk = lex(); + while (!((tk = lex()) == '*' && (tk = lex()) == '/')) { + // nothing + } + tk = lex(); + } } -static void gcc_parse_attribute() { +static char gcc_parse_attribute(void) { + char ch; + + while (tk == TK_NEG7) + tk = lex(); + + if (tk != '"') + CError_Error(CErrorStr105); + + while ((tk = lex()) != TK_IDENTIFIER) { + // nothing + } + + ch = tkidentifier->name[0]; + + if ((tk = lex()) != '"') + CError_Error(CErrorStr105); + tk = lex(); + + return ch; } -static void gcc_parse_name() { +static void gcc_parse_name(Boolean flag, char attribute) { + IALookupResult *nameentry; + ENode *expr; + Object *tempobj; + ENode *tempexpr; + Statement *stmt; + + while (tk == TK_NEG7) + tk = lex(); + + if (tk != '(') + CError_Error(CErrorStr114); + + tk = lex(); + + if (flag) { + if (tk != TK_IDENTIFIER) + CError_Error(CErrorStr105); + + InlineAsm_LookupSymbol(tkidentifier, &gcc_name_list[++gcc_name_list_index]); + if (gcc_name_list[gcc_name_list_index].object && gcc_name_list[gcc_name_list_index].object->u.var.info) + gcc_name_list[gcc_name_list_index].object->u.var.info->used = 1; + + tk = lex(); + } else { + in_assembler = 0; + cprep_nostring = 0; + nameentry = &gcc_name_list[++gcc_name_list_index]; + + expr = expression(); + if (attribute == 'i' || attribute == 'I') { + if (!ENODE_IS(expr, EINTCONST)) + CError_Error(CErrorStr144); + nameentry->value = CInt64_GetULong(&expr->data.intval); + nameentry->has_value = 1; + } else { + tempobj = create_temp_object(expr->rtype); + tempexpr = create_objectnode(tempobj); + if (tempobj->u.var.info) + tempobj->u.var.info->used = 1; + expr = makediadicnode(tempexpr, expr, EASS); + + stmt = CFunc_InsertBeforeStatement(ST_EXPRESSION, first_ST_ASM); + first_ST_ASM = stmt->next; + if (!first_ST_ASM->next) + curstmt = first_ST_ASM; + stmt->expr = expr; + + nameentry->name = tempobj->name; + nameentry->object = tempobj; + nameentry->label = NULL; + nameentry->type = NULL; + nameentry->has_value = 0; + } + } + + cprep_nostring = 1; + in_assembler = 1; + + if (tk != ')') + CError_Error(CErrorStr115); + tk = lex(); } -static void gcc_parse_expression() { +static void gcc_parse_expression(Boolean flag) { + while (1) { + gcc_parse_name(flag, gcc_parse_attribute()); + if (tk != ',') + break; + tk = lex(); + } } -static void gcc_parse_input() { +static void gcc_parse_input(void) { + if (tk == ':') { + if ((tk = lex()) == ':' || tk == ')' || tk == '}') + return; + gcc_parse_expression(0); + } } -static void gcc_parse_output() { +static void gcc_parse_output(void) { + if (tk == ':') { + if ((tk = lex()) == ':' || tk == ')' || tk == '}') + return; + gcc_parse_expression(1); + } } -static void gcc_parse_killed() { +static void gcc_parse_killed(void) { + if (tk == ':') { + while (1) { + if ((tk = lex()) != '"') + return; + + tk = lex(); + while (1) { + if (tk == '"') { + if (lookahead() == ',') { + tk = lex(); + break; + } + tk = lex(); + return; + } + tk = lex(); + } + } + } } -static void gcc_replace_arg_st_asm() { +static void gcc_replace_arg_st_asm(Statement *stmt) { + InlineAsm *ia; + int i; + IAOperand *op; + short effect; + short rclass; + SInt32 num; + + if ((ia = (InlineAsm *) stmt->expr)) { + for (i = 0, op = ia->args; i < ia->argcount; i++, op++) { + switch (op->type) { + case IAOpnd_Imm: + case IAOpnd_Reg: + case IAOpnd_3: + case IAOpnd_4: + case IAOpnd_Lab: + break; + + case IAOpnd_6: + if (op->u.unk6.unk4 == 2) { + effect = op->u.unk6.effect; + rclass = op->u.unk6.rclass; + num = op->u.unk6.num; + op->type = IAOpnd_Reg; + op->u.reg.effect = effect; + op->u.reg.rclass = rclass; + op->u.reg.object = NULL; + if (num <= gcc_name_list_index) + op->u.reg.object = gcc_name_list[num].object; + else + CError_Error(CErrorStr144); + op->u.reg.num = 0; + } else { + CError_FATAL(365); + } + break; + + case IAOpnd_7: + op->type = IAOpnd_Imm; + op->u.imm.value = gcc_name_list[op->u.unk7.value].value; + break; + } + } + } } -static void gcc_replace_arg() { +static void gcc_replace_arg(void) { + Statement *stmt; + + for (stmt = first_ST_ASM; stmt; stmt = stmt->next) { + if (stmt->type == ST_ASM) + gcc_replace_arg_st_asm(stmt); + } } void InlineAsm_gcc_parse(void) { + gcc_name_list_index = -1; + cprep_eoltokens = 0; + + if (tk == TK_NEG7) + tk = lex(); + + gcc_parse_output(); + gcc_parse_input(); + gcc_parse_killed(); + gcc_replace_arg(); } diff --git a/compiler_and_linker/unsorted/InlineAsm.c b/compiler_and_linker/unsorted/InlineAsm.c index 628c678..e800327 100644 --- a/compiler_and_linker/unsorted/InlineAsm.c +++ b/compiler_and_linker/unsorted/InlineAsm.c @@ -591,7 +591,7 @@ Object *InlineAsm_GetObjectOffset(InlineAsm *ia, SInt32 index, SInt32 *offset) { for (i = 0, counter = 0, op = ia->args; i < ia->argcount; i++, op++) { if (op->type == IAOpnd_3) { if (counter++ == index) { - *offset = ((SInt32) &op->u.obj.obj) - ((SInt32) ia); + *offset = ((intptr_t) &op->u.obj.obj) - ((intptr_t) ia); return op->u.obj.obj; } } diff --git a/compiler_and_linker/unsorted/InlineAsmPPC.c b/compiler_and_linker/unsorted/InlineAsmPPC.c index 19c8fdc..e3a5f98 100644 --- a/compiler_and_linker/unsorted/InlineAsmPPC.c +++ b/compiler_and_linker/unsorted/InlineAsmPPC.c @@ -1,32 +1,29 @@ #include "compiler/InlineAsmPPC.h" #include "compiler/CError.h" +#include "compiler/CExpr.h" #include "compiler/CInt64.h" #include "compiler/CFunc.h" #include "compiler/CMachine.h" #include "compiler/CParser.h" #include "compiler/CPrep.h" #include "compiler/CPrepTokenizer.h" -#include "compiler/TOC.h" +#include "compiler/Alias.h" +#include "compiler/CodeGen.h" +#include "compiler/CodeGenOptPPC.h" +#include "compiler/CompilerTools.h" +#include "compiler/Exceptions.h" #include "compiler/FuncLevelAsmPPC.h" #include "compiler/InlineAsm.h" #include "compiler/InlineAsmMnemonicsPPC.h" #include "compiler/InlineAsmRegisters.h" #include "compiler/InlineAsmRegistersPPC.h" -#include "compiler/CodeGen.h" -#include "compiler/CodeGenOptPPC.h" -#include "compiler/PPCError.h" -#include "compiler/RegisterInfo.h" -#include "compiler/objects.h" -#include "compiler/CExpr.h" #include "compiler/PCode.h" #include "compiler/PCodeUtilities.h" +#include "compiler/PPCError.h" +#include "compiler/RegisterInfo.h" #include "compiler/StackFrame.h" -#include "compiler/CompilerTools.h" -#include "compiler/Alias.h" - -// TODO: move me -extern int countexceptionactionregisters(ExceptionAction *); -extern void noteexceptionactionregisters(ExceptionAction *, PCodeArg *); +#include "compiler/TOC.h" +#include "compiler/objects.h" char asm_alloc_flags[10]; Section sm_section; @@ -35,17 +32,12 @@ SInt32 fralloc_parameter_area_size; Boolean user_responsible_for_frame; Boolean supports_hardware_fpu; UInt32 assembledinstructions; -UInt8 assembler_type; +AssemblerType assembler_type; char volatileasm; Boolean InlineAsm_gccmode; Boolean InlineAsm_labelref; CLabel *pic_base_label; -enum { - NO_REG = 0, - INVALID_PIC_REG = -2 -}; - // forward decls static SInt32 InlineAsm_ConstantExpressionPPC(SInt32 value); static Object *isvariableoperand(void); @@ -71,8 +63,9 @@ static void IllegalObjectOperator(HashNameNode *name1, HashNameNode *name2, shor case TK_SHR: opstr = ">>"; break; case '<': opstr = "<"; break; case '>': opstr = ">"; break; - case TK_LESS_EQUAL: opstr = "<="; break; - case TK_GREATER_EQUAL: opstr = ">="; break; + // bug? these two seem swapped + case TK_LESS_EQUAL: opstr = ">="; break; + case TK_GREATER_EQUAL: opstr = "<="; break; case TK_LOGICAL_EQ: opstr = "=="; break; case TK_LOGICAL_NE: opstr = "!="; break; case '&': opstr = "&"; break; @@ -1478,7 +1471,7 @@ static int mnemonic_has_overflow(char *buf) { return result; } -static int mnemonic_has_absolute(char *buf) { +static int mnemonic_has_absolute(const char *buf) { int result = 0; char last = buf[strlen(buf) - 1]; @@ -1488,7 +1481,7 @@ static int mnemonic_has_absolute(char *buf) { return result; } -static int mnemonic_has_linkregister(char *buf) { +static int mnemonic_has_linkregister(const char *buf) { int result = 0; char last = buf[strlen(buf) - 1]; @@ -1552,7 +1545,7 @@ void InlineAsm_InitializePPC(void) { cpu |= 0x40000000; } -void InlineAsm_Initialize(UInt8 assemblertype) { +void InlineAsm_Initialize(AssemblerType assemblertype) { assembler_type = assemblertype; if (assembler_type == 0) { @@ -1608,7 +1601,7 @@ static InlineAsm *InlineAsm_CreateFrFree(void) { return ia; } -SInt32 InlineAsm_IsDirective(UInt8 assemblertype) { +SInt32 InlineAsm_IsDirective(AssemblerType assemblertype) { char *name; SInt32 directive = IADirective_Null; @@ -1619,7 +1612,7 @@ SInt32 InlineAsm_IsDirective(UInt8 assemblertype) { name = tkidentifier->name; if (!strcmp(name, "machine")) { directive = IADirective_Machine; - } else if (assemblertype == 1) { + } else if (assemblertype == AssemblerType_1) { if (!strcmp(name, "entry")) { directive = IADirective_Entry; } else if (!strcmp(name, "fralloc")) { @@ -1815,6 +1808,7 @@ void InlineAsm_ScanAssemblyInstruction(void) { Boolean flag1; Boolean flag2; SInt32 directive; + OpcodeInfo *info; char buf[20]; flag1 = 0; @@ -1837,9 +1831,10 @@ void InlineAsm_ScanAssemblyInstruction(void) { if (!mnemonic) CError_Error(CErrorStr261); - flag3 = (FLAG_SET_F(opcodeinfo[mnemonic->x4].flags) & fPCodeFlag4000000) && (mnemonic->x10 & 0x400); - flag4 = (FLAG_SET_T(opcodeinfo[mnemonic->x4].flags) & fPCodeFlag20000000) && (mnemonic->x10 & 2); - flag5 = (FLAG_SET_T(opcodeinfo[mnemonic->x4].flags) & fPCodeFlag2000000) && (mnemonic->x10 & 1); + info = &opcodeinfo[mnemonic->x4]; + flag3 = (FLAG_SET_F(info->flags) & fPCodeFlag4000000) && (mnemonic->x10 & 0x400); + flag4 = (FLAG_SET_T(info->flags) & fPCodeFlag20000000) && (mnemonic->x10 & 2); + flag5 = (FLAG_SET_T(info->flags) & fPCodeFlag2000000) && (mnemonic->x10 & 1); if ((cpu == CPUMask_Generic) && (cpu & CPUFLAG_LOW_MASK) != ((cpu & mnemonic->cpu) & CPUFLAG_LOW_MASK)) { CError_Error(CErrorStr152); @@ -1901,8 +1896,7 @@ void InlineAsm_ScanAssemblyInstruction(void) { ++assembledinstructions; } -static PCode *InlineAsm_TranslateIRtoPCodePPC(InlineAsm *ia, int argcount, UInt8 assemblertype) { - OpcodeInfo *info; +static PCode *InlineAsm_TranslateIRtoPCodePPC(InlineAsm *ia, int argcount, AssemblerType assemblertype) { PCode *pc; int index; int extra_args; @@ -1911,6 +1905,7 @@ static PCode *InlineAsm_TranslateIRtoPCodePPC(InlineAsm *ia, int argcount, UInt8 SInt32 buffersize; IAOperand *src; PCodeArg *dest; + OpcodeInfo *info; info = &opcodeinfo[ia->opcode]; index = 0; @@ -2106,7 +2101,7 @@ static PCode *InlineAsm_TranslateIRtoPCodePPC(InlineAsm *ia, int argcount, UInt8 dest->kind = PCOp_REGISTER; dest->arg = RegClass_GPR; dest->data.reg.reg = i; - dest->data.reg.effect = (short) ((ia->opcode == PC_LMW) ? EffectWrite : EffectRead); + dest->data.reg.effect = ((ia->opcode == PC_LMW) ? EffectWrite : EffectRead); } } @@ -2485,8 +2480,8 @@ void CodeGen_GetAsmEffects(Statement *stmt, IAEffects *effects) { CError_FATAL(4087); } - CError_ASSERT(4090, effects->numoperands <= 16); - CError_ASSERT(4093, effects->numlabels <= 16); + CError_ASSERT(4090, (UInt32) effects->numoperands <= IAMaxOperands); + CError_ASSERT(4093, (UInt32) effects->numlabels <= IAMaxLabels); } for (i = 0, op = ia->args; i < ia->argcount; i++, op++) { @@ -2526,7 +2521,7 @@ void CodeGen_GetAsmEffects(Statement *stmt, IAEffects *effects) { break; } - CError_ASSERT(4151, effects->numoperands <= 16); + CError_ASSERT(4151, (UInt32) effects->numoperands <= IAMaxOperands); } if ((info->flags & (fPCodeFlag1 | fPCodeFlag8)) && (SInt32)effects->numlabels == 0) diff --git a/compiler_and_linker/unsorted/InstrSelection.c b/compiler_and_linker/unsorted/InstrSelection.c index ac60baf..1916711 100644 --- a/compiler_and_linker/unsorted/InstrSelection.c +++ b/compiler_and_linker/unsorted/InstrSelection.c @@ -4,20 +4,20 @@ #include "compiler/CMachine.h" #include "compiler/CParser.h" #include "compiler/CodeGen.h" +#include "compiler/CompilerTools.h" +#include "compiler/FunctionCalls.h" +#include "compiler/Intrinsics.h" #include "compiler/Operands.h" #include "compiler/PCode.h" #include "compiler/PCodeInfo.h" #include "compiler/PCodeUtilities.h" #include "compiler/RegisterInfo.h" +#include "compiler/StructMoves.h" #include "compiler/TOC.h" -#include "compiler/CompilerTools.h" #include "compiler/enode.h" #include "compiler/objects.h" #include "compiler/types.h" -// TODO: move me -extern void move_block(Operand *, Operand *, SInt32, SInt32); - PrecomputedOperand *precomputedoperands; void (*cgdispatch[MAXEXPR + 1])(ENode *, short, short, Operand *); @@ -103,8 +103,7 @@ void gen_DEFINE(ENode *expr, short outputReg, short outputRegHi, Operand *output void gen_REUSE(ENode *expr, short outputReg, short outputRegHi, Operand *output) { ENode *inner = expr->data.monadic; -#line 250 - CError_ASSERT(ENODE_IS(inner, EDEFINE)); + CError_ASSERT(250, ENODE_IS(inner, EDEFINE)); gen_DEFINE(inner, outputReg, outputRegHi, output); } @@ -250,8 +249,7 @@ void gen_INDIRECT(ENode *expr, short outputReg, short outputRegHi, Operand *outp output->optype = OpndType_CRField; break; default: -#line 456 - CError_FATAL(); + CError_FATAL(456); } output->reg = vi->reg; output->object = NULL; @@ -386,8 +384,7 @@ void gen_FORCELOAD(ENode *expr, short outputReg, short outputRegHi, Operand *out else ENSURE_GPR(output, inner->rtype, outputReg); } else if (!IS_TYPE_VOID(inner->rtype)) { -#line 681 - CError_FATAL(); + CError_FATAL(681); } } @@ -1114,8 +1111,7 @@ void gen_ASS(ENode *expr, short outputReg, short outputRegHi, Operand *output) { if (ENODE_IS(left, EINDIRECT)) { left = left->data.monadic; } else { -#line 1759 - CError_FATAL(); + CError_FATAL(1759); } right = expr->data.cond.expr2; } else { @@ -1149,8 +1145,7 @@ void gen_ASS(ENode *expr, short outputReg, short outputRegHi, Operand *output) { output->optype = OpndType_VR; break; default: -#line 1810 - CError_FATAL(); + CError_FATAL(1810); } if (opright.reg != vi->reg) { PCodeArg a, b; @@ -1382,14 +1377,12 @@ void gen_TYPCON(ENode *expr, short outputReg, short outputRegHi, Operand *output } else if (srctype->size == dsttype->size) { GEN_NODE_TO_REG(inner, outputReg, 0, output); } else { -#line 2224 - CError_FATAL(); + CError_FATAL(2224); } } void gen_BITFIELD(ENode *expr, short outputReg, short outputRegHi, Operand *output) { -#line 2238 - CError_FATAL(); + CError_FATAL(2238); } void gen_INTCONST(ENode *expr, short outputReg, short outputRegHi, Operand *output) { @@ -1403,13 +1396,11 @@ void gen_INTCONST(ENode *expr, short outputReg, short outputRegHi, Operand *outp } void gen_FLOATCONST(ENode *expr, short outputReg, short outputRegHi, Operand *output) { -#line 2294 - CError_FATAL(); + CError_FATAL(2294); } void gen_STRINGCONST(ENode *expr, short outputReg, short outputRegHi, Operand *output) { -#line 2308 - CError_FATAL(); + CError_FATAL(2308); } static Boolean COND_is_ABS_MatchNodes(ENode *cond, ENode *expr1, ENode *expr2) { @@ -1619,6 +1610,8 @@ void gen_COND(ENode *expr, short outputReg, short outputRegHi, Operand *output) Boolean flag; Operand op; int fneg_reg; + int fneg_reg2; + int fneg_reg3; int fsel_reg; int final_reg; @@ -1648,8 +1641,7 @@ void gen_COND(ENode *expr, short outputReg, short outputRegHi, Operand *output) right = tmp; break; default: -#line 2780 - CError_FATAL(); + CError_FATAL(2780); } if (ENODE_IS(left, EFLOATCONST) && CMach_FloatIsZero(left->data.floatval)) { @@ -1680,12 +1672,12 @@ void gen_COND(ENode *expr, short outputReg, short outputRegHi, Operand *output) GEN_NODE_TO_FPR(expr1, &op1, expr1->rtype, 0); GEN_NODE_TO_FPR(expr2, &op2, expr2->rtype, 0); - fneg_reg = ALLOC_FPR(); - emitpcode(PC_FNEG, fneg_reg, op.reg); + fneg_reg2 = ALLOC_FPR(); + emitpcode(PC_FNEG, fneg_reg2, op.reg); fsel_reg = ALLOC_FPR(); emitpcode(PC_FSEL, fsel_reg, op.reg, op1.reg, op2.reg); final_reg = outputReg ? outputReg : ALLOC_FPR(); - emitpcode(PC_FSEL, final_reg, fneg_reg, fsel_reg, op2.reg); + emitpcode(PC_FSEL, final_reg, fneg_reg2, fsel_reg, op2.reg); } break; case ELESS: @@ -1695,18 +1687,17 @@ void gen_COND(ENode *expr, short outputReg, short outputRegHi, Operand *output) GEN_NODE_TO_FPR(expr1, &op1, expr1->rtype, 0); GEN_NODE_TO_FPR(expr2, &op2, expr2->rtype, 0); - fneg_reg = op.reg; + fneg_reg3 = op.reg; if (flag) { - fneg_reg = ALLOC_FPR(); - emitpcode(PC_FNEG, fneg_reg, op.reg); + fneg_reg3 = ALLOC_FPR(); + emitpcode(PC_FNEG, fneg_reg3, op.reg); } final_reg = outputReg ? outputReg : ALLOC_FPR(); - emitpcode(PC_FSEL, final_reg, fneg_reg, op1.reg, op2.reg); + emitpcode(PC_FSEL, final_reg, fneg_reg3, op1.reg, op2.reg); break; default: -#line 2862 - CError_FATAL(); + CError_FATAL(2862); } output->optype = OpndType_FPR; @@ -1814,8 +1805,7 @@ void gen_COND(ENode *expr, short outputReg, short outputRegHi, Operand *output) ENSURE_GPR(&op1, expr1->rtype, 0); emitpcode(PC_AND, reg1, op1.reg, isel_op1.reg); } else { -#line 3119 - CError_FATAL(); + CError_FATAL(3119); } output->optype = OpndType_GPR; @@ -1851,8 +1841,7 @@ void gen_COND(ENode *expr, short outputReg, short outputRegHi, Operand *output) return; default: -#line 3168 - CError_FATAL(); + CError_FATAL(3168); } } @@ -2157,9 +2146,8 @@ void gen_CONDASS(ENode *expr, short outputReg, short outputRegHi, Operand *outpu flag = 0; memclrw(&op, sizeof(Operand)); -#line 3704 - CError_ASSERT(ENODE_IS(expr1, EINDIRECT)); - CError_ASSERT(ENODE_IS(expr1->data.monadic, EOBJREF)); + CError_ASSERT(3704, ENODE_IS(expr1, EINDIRECT)); + CError_ASSERT(3705, ENODE_IS(expr1->data.monadic, EOBJREF)); tmpreg = OBJECT_REG(expr1->data.monadic->data.objref); final_reg = outputReg ? tmpreg : ALLOC_FPR(); @@ -2187,8 +2175,7 @@ void gen_CONDASS(ENode *expr, short outputReg, short outputRegHi, Operand *outpu flag2 = 0; break; default: -#line 3744 - CError_FATAL(); + CError_FATAL(3744); } if (ENODE_IS(left, EFLOATCONST) && CMach_FloatIsZero(left->data.floatval)) { @@ -2251,8 +2238,7 @@ void gen_CONDASS(ENode *expr, short outputReg, short outputRegHi, Operand *outpu emitpcode(PC_FSEL, final_reg, fneg_reg, op2.reg, op1.reg); break; default: -#line 2862 - CError_FATAL(); + CError_FATAL(2862); } if (op3.optype != OpndType_FPR) @@ -2270,10 +2256,8 @@ void gen_CONDASS(ENode *expr, short outputReg, short outputRegHi, Operand *outpu ENode *abs_expr; memclrw(&isel_op, sizeof(Operand)); -#line 3966 - CError_ASSERT(ENODE_IS(expr1, EINDIRECT)); -#line 3968 - CError_ASSERT(ENODE_IS(expr1->data.monadic, EOBJREF)); + CError_ASSERT(3966, ENODE_IS(expr1, EINDIRECT)); + CError_ASSERT(3968, ENODE_IS(expr1->data.monadic, EOBJREF)); if (CONDASS_is_ABS(cond, expr1, expr2)) { if (ENODE_IS(cond->data.diadic.left, EASS)) @@ -2282,14 +2266,12 @@ void gen_CONDASS(ENode *expr, short outputReg, short outputRegHi, Operand *outpu GEN_NODE(cond->data.diadic.right, &isel_op); outputReg = OBJECT_REG(expr1->data.monadic->data.objref); -#line 3979 - CError_ASSERT(outputReg); + CError_ASSERT(3979, outputReg); GEN_NODE(expr1, &op1); op3 = op1; -#line 3986 - CError_ASSERT(op3.optype == OpndType_GPR && op3.reg == outputReg); + CError_ASSERT(3986, op3.optype == OpndType_GPR && op3.reg == outputReg); ENSURE_GPR(&op1, expr1->rtype, 0); if (expr1->rtype->size < 4) @@ -2317,6 +2299,10 @@ void gen_CONDASS(ENode *expr, short outputReg, short outputRegHi, Operand *outpu } void gen_FUNCCALL(ENode *expr, short outputReg, short outputRegHi, Operand *output) { + if (is_intrinsic_function_call(expr)) + call_intrinsic_function(expr, outputReg, output); + else + call_function(expr, output); } void gen_OBJREF(ENode *expr, short outputReg, short outputRegHi, Operand *output) { @@ -2324,8 +2310,7 @@ void gen_OBJREF(ENode *expr, short outputReg, short outputRegHi, Operand *output } void gen_UNEXPECTED(ENode *expr, short outputReg, short outputRegHi, Operand *output) { -#line 4160 - CError_FATAL(); + CError_FATAL(4160); } static int small(ENode *expr) { @@ -2658,8 +2643,7 @@ void gen_LOGICAL(ENode *expr, short outputReg, short outputRegHi, Operand *outpu tmpreg1 = ALLOC_GPR(); tmpreg2 = ALLOC_GPR(); -#line 4853 - CError_ASSERT(output->optype == OpndType_GPR); + CError_ASSERT(4853, output->optype == OpndType_GPR); emitpcode(PC_CNTLZW, tmpreg2, output->reg); emitpcode(PC_RLWINM, tmpreg1, tmpreg2, 27, 5, 31); @@ -2685,8 +2669,7 @@ void gen_LOGICAL(ENode *expr, short outputReg, short outputRegHi, Operand *outpu tmpreg1 = ALLOC_GPR(); tmpreg2 = ALLOC_GPR(); -#line 4883 - CError_ASSERT(output->optype == OpndType_GPR); + CError_ASSERT(4883, output->optype == OpndType_GPR); emitpcode(PC_CNTLZW, tmpreg2, output->reg); emitpcode(PC_RLWINM, tmpreg1, tmpreg2, 27, 5, 31); @@ -2810,8 +2793,7 @@ void logical_expression(ENode *cond, PCodeLabel *if_true, PCodeLabel *if_false, branch_conditional(op.reg, op.regOffset, 1, if_true); break; default: -#line 5160 - CError_FATAL(); + CError_FATAL(5160); } } @@ -2829,8 +2811,7 @@ static void logical_expression_nobranch(ENode *cond, Boolean invert, Operand *ou case ENOTEQU: if (invert) { ENodeType nt = invert_relop(cond->type); -#line 5190 - CError_ASSERT(nt != cond->type); + CError_ASSERT(5190, nt != cond->type); cond->type = nt; } @@ -2841,8 +2822,7 @@ static void logical_expression_nobranch(ENode *cond, Boolean invert, Operand *ou break; default: -#line 5206 - CError_FATAL(); + CError_FATAL(5206); } } @@ -2999,8 +2979,7 @@ void gen_condition_gpr(ENode *cond, Operand *output, short outputReg) { pc->args[1].data.reg.reg, (r6 + r7 + 1) & 31, 31, 31); } else { -#line 5434 - CError_FATAL(); + CError_FATAL(5434); } output->optype = OpndType_GPR; output->reg = reg; @@ -3061,8 +3040,7 @@ void gen_condition_gpr(ENode *cond, Operand *output, short outputReg) { (r6 + r7 + 1) & 31, 31, 31); emitpcode(PC_XORI, reg, tmpreg, 1); } else { -#line 5503 - CError_FATAL(); + CError_FATAL(5503); } output->optype = OpndType_GPR; output->reg = reg; @@ -3265,8 +3243,7 @@ void gen_condition_gpr(ENode *cond, Operand *output, short outputReg) { } default: -#line 5777 - CError_FATAL(); + CError_FATAL(5777); } } @@ -3589,8 +3566,7 @@ void I8_gen_ADD(ENode *expr, short outputReg, short outputRegHi, Operand *output case 1 + 8: case 2 + 8: case 4 + 8: -#line 6933 - CError_ASSERT(skipleft == 8); + CError_ASSERT(6933, skipleft == 8); if (!is_uns) { tmpreg2 = ALLOC_GPR(); emitpcode(PC_SRAWI, tmpreg2, opright.reg, 31); @@ -3612,8 +3588,7 @@ void I8_gen_ADD(ENode *expr, short outputReg, short outputRegHi, Operand *output emitpcode(PC_ADDE, regHi, opleft.regHi, opright.regHi); break; default: -#line 6979 - CError_FATAL(); + CError_FATAL(6979); } output->optype = OpndType_GPRPair; @@ -3745,8 +3720,7 @@ void I8_gen_SUB(ENode *expr, short outputReg, short outputRegHi, Operand *output emitpcode(PC_SUBFE, regHi, opright.regHi, opleft.regHi); break; default: -#line 7211 - CError_FATAL(); + CError_FATAL(7211); } output->optype = OpndType_GPRPair; @@ -3840,10 +3814,8 @@ int I8_log2n(UInt64 val) { } void I8_ShiftLeftImmediate(Operand opnd, SInt32 value, int is_unsigned, SInt32 size, short reg, short regHi) { - if (opnd.reg == reg || opnd.regHi == regHi || opnd.reg == regHi || opnd.regHi == reg) { -#line 7703 - CError_FATAL(); - } + if (opnd.reg == reg || opnd.regHi == regHi || opnd.reg == regHi || opnd.regHi == reg) + CError_FATAL(7703); if (value < 32) { emitpcode(PC_RLWINM, reg, opnd.reg, value, 0, 31 - value); @@ -3860,8 +3832,7 @@ void I8_ShiftLeftImmediate(Operand opnd, SInt32 value, int is_unsigned, SInt32 s emitpcode(PC_RLWINM, regHi, opnd.reg, value - 32, 0, 63 - value); emitpcode(PC_LI, reg, 0); } else { -#line 7732 - CError_FATAL(); + CError_FATAL(7732); } } @@ -3871,10 +3842,8 @@ void I8_ShiftRightImmediate(Operand opnd, SInt32 value, int is_unsigned, short r short tmpreg3; short tmpreg4; - if (opnd.reg == reg || opnd.regHi == regHi || opnd.reg == regHi || opnd.regHi == reg) { -#line 7756 - CError_FATAL(); - } + if (opnd.reg == reg || opnd.regHi == regHi || opnd.reg == regHi || opnd.regHi == reg) + CError_FATAL(7756); if (value < 32) { emitpcode(PC_RLWINM, reg, opnd.reg, 32 - value, 0, 31); @@ -3927,8 +3896,7 @@ void I8_ShiftRightImmediate(Operand opnd, SInt32 value, int is_unsigned, short r emitpcode(PC_SRAWI, regHi, opnd.regHi, 31); } } else { -#line 7866 - CError_FATAL(); + CError_FATAL(7866); } } @@ -3957,10 +3925,8 @@ void I8_gen_MUL(ENode *expr, short outputReg, short outputRegHi, Operand *output skipleft = GetSizeSkip(left); skipright = GetSizeSkip(right); - if (ENODE_IS(right, EINTCONST) && ENODE_IS(left, EINTCONST)) { -#line 7900 - CError_FATAL(); - } + if (ENODE_IS(right, EINTCONST) && ENODE_IS(left, EINTCONST)) + CError_FATAL(7900); if (ENODE_IS(left, EINTCONST)) leftval = left->data.intval.lo + (((SInt64) ((skipleft < 8) ? 0 : left->data.intval.hi)) << 32); @@ -4066,8 +4032,7 @@ void I8_gen_MUL(ENode *expr, short outputReg, short outputRegHi, Operand *output case 1 + 8: case 2 + 8: case 4 + 8: -#line 8097 - CError_ASSERT(skipleft == 8); + CError_ASSERT(8097, skipleft == 8); if (ENODE_IS(left, EINTCONST) && FITS_IN_SHORT2(left->data.intval.lo) && left->data.intval.hi == 0) { emitpcode(PC_MULLI, reg, opright.reg, LOW_PART(left->data.intval.lo)); if (is_uns) @@ -4143,8 +4108,7 @@ void I8_gen_MUL(ENode *expr, short outputReg, short outputRegHi, Operand *output } break; default: -#line 8218 - CError_FATAL(); + CError_FATAL(8218); } } @@ -4206,12 +4170,10 @@ void I8_gen_ASS(ENode *expr, short outputReg, short outputRegHi, Operand *output type = expr->rtype; if (ENODE_IS(expr, ECONDASS)) { left = expr->data.cond.expr1; - if (ENODE_IS(left, EINDIRECT)) { + if (ENODE_IS(left, EINDIRECT)) left = left->data.monadic; - } else { -#line 8328 - CError_FATAL(); - } + else + CError_FATAL(8238); right = expr->data.cond.expr2; } else { left = expr->data.diadic.left; @@ -4225,8 +4187,7 @@ void I8_gen_ASS(ENode *expr, short outputReg, short outputRegHi, Operand *output vi = Registers_GetVarInfo(left->data.objref); GEN_NODE_TO_REG(right, vi->reg, vi->regHi, &opright); if (vi->rclass != RegClass_GPR) { -#line 8348 - CError_FATAL(); + CError_FATAL(8348); } else { coerce_to_register_pair(&opright, type, vi->reg, vi->regHi); *output = opright; @@ -4239,8 +4200,7 @@ void I8_gen_ASS(ENode *expr, short outputReg, short outputRegHi, Operand *output coerce_to_register_pair(&opright, right->rtype, 0, 0); if (ENODE_IS(left, EBITFIELD)) { -#line 8376 - CError_FATAL(); + CError_FATAL(8376); } else { GEN_NODE(left, &opleft); indirect(&opleft, left); @@ -4286,8 +4246,7 @@ void I8_gen_POSTINCDEC(ENode *expr, short outputReg, short outputRegHi, Operand return; } -#line 8446 - CError_ASSERT(!ENODE_IS(inner, EBITFIELD)); + CError_ASSERT(8446, !ENODE_IS(inner, EBITFIELD)); GEN_NODE(inner, &op1); indirect(&op1, inner); @@ -4329,8 +4288,7 @@ void I8_gen_INDIRECT(ENode *expr, short outputReg, short outputRegHi, Operand *o output->optype = OpndType_FPR; break; default: -#line 8511 - CError_FATAL(); + CError_FATAL(8511); } output->reg = vi->reg; @@ -4340,8 +4298,7 @@ void I8_gen_INDIRECT(ENode *expr, short outputReg, short outputRegHi, Operand *o } if (ENODE_IS(inner, EBITFIELD)) { -#line 8529 - CError_FATAL(); + CError_FATAL(8529); return; } @@ -4430,8 +4387,7 @@ void I8_gen_condition(ENode *cond, Operand *output, int write_to_gpr) { } } -#line 8704 - CError_ASSERT(opleft.optype == OpndType_GPRPair && opright.optype == OpndType_GPRPair); + CError_ASSERT(8704, opleft.optype == OpndType_GPRPair && opright.optype == OpndType_GPRPair); switch (cond->type) { case EEQU: @@ -4525,8 +4481,7 @@ void I8_gen_condition(ENode *cond, Operand *output, int write_to_gpr) { } break; default: -#line 8814 - CError_FATAL(); + CError_FATAL(8814); } } @@ -4569,8 +4524,7 @@ void I8_gen_SHL_SHR(ENode *expr, short outputReg, short outputRegHi, Operand *ou opright.optype = OpndType_GPR; } -#line 8890 - CError_ASSERT(opleft.optype == OpndType_GPRPair && opright.optype == OpndType_GPR); + CError_ASSERT(8890, opleft.optype == OpndType_GPRPair && opright.optype == OpndType_GPR); if (opleft.regHi != high_reg) emitpcode(PC_MR, high_reg, opleft.regHi); @@ -4587,8 +4541,7 @@ void I8_gen_SHL_SHR(ENode *expr, short outputReg, short outputRegHi, Operand *ou } else if (ENODE_IS(expr, ESHL)) { branch_subroutine(rt_shl2i, 0, used_regs); } else { -#line 8909 - CError_FATAL(); + CError_FATAL(8909); } emitpcode(PC_MR, output->reg, low_reg); @@ -4623,8 +4576,7 @@ void I8_gen_DIV_MOD(ENode *expr, short outputReg, short outputRegHi, Operand *ou if (ENODE_IS(right, EINTCONST)) constval = (((SInt64) right->data.intval.hi) << 32) + right->data.intval.lo; if (ENODE_IS(right, EINTCONST) && ((shift = I8_log2n(constval)) > 0)) { -#line 8976 - CError_ASSERT(opleft.optype == OpndType_GPRPair); + CError_ASSERT(8976, opleft.optype == OpndType_GPRPair); if (ENODE_IS(expr, EDIV)) { I8_ShiftRightImmediate(opleft, shift, is_uns, output->reg, output->regHi, 1); if (!is_uns) { @@ -4643,8 +4595,7 @@ void I8_gen_DIV_MOD(ENode *expr, short outputReg, short outputRegHi, Operand *ou emitpcode(PC_RLWINM, output->regHi, opleft.regHi, 0, 32 - (shift - 32), 31); emitpcode(PC_MR, output->reg, opleft.reg); } else { -#line 9018 - CError_FATAL(); + CError_FATAL(9018); } } else { short tmpreg1 = ALLOC_GPR(); @@ -4663,8 +4614,7 @@ void I8_gen_DIV_MOD(ENode *expr, short outputReg, short outputRegHi, Operand *ou GEN_NODE(right, &opright); coerce_to_register_pair(&opright, right->rtype, 0, 0); -#line 9048 - CError_ASSERT(opleft.optype == OpndType_GPRPair && opright.optype == OpndType_GPRPair); + CError_ASSERT(9048, opleft.optype == OpndType_GPRPair && opright.optype == OpndType_GPRPair); if (opleft.regHi != high_reg) emitpcode(PC_MR, high_reg, opleft.regHi); @@ -4686,8 +4636,7 @@ void I8_gen_DIV_MOD(ENode *expr, short outputReg, short outputRegHi, Operand *ou else branch_subroutine(rt_mod2i, 0, used_regs); } else { -#line 9074 - CError_FATAL(); + CError_FATAL(9074); } emitpcode(PC_MR, output->reg, low_reg); @@ -4745,8 +4694,7 @@ void I8_gen_TYPCON(ENode *expr, short outputReg, short outputRegHi, Operand *out } if (srctype->size < dsttype->size) { -#line 9171 - CError_ASSERT(TYPE_IS_8BYTES(dsttype)); + CError_ASSERT(9171, TYPE_IS_8BYTES(dsttype)); GEN_NODE(inner, output); if (srctype->size < 4 && @@ -4769,8 +4717,7 @@ void I8_gen_TYPCON(ENode *expr, short outputReg, short outputRegHi, Operand *out if (IS_TYPE_POINTER(srctype)) { GEN_NODE_TO_REG(inner, outputReg, 0, output); -#line 9200 - CError_ASSERT(TYPE_IS_8BYTES(expr->rtype)); + CError_ASSERT(9200, TYPE_IS_8BYTES(expr->rtype)); GEN_NODE_TO_REG(inner, outputReg, 0, output); regHi = outputRegHi ? outputRegHi : ALLOC_GPR(); @@ -4790,8 +4737,7 @@ void I8_gen_TYPCON(ENode *expr, short outputReg, short outputRegHi, Operand *out if (IS_TYPE_FLOAT(srctype)) { if (IS_TYPE_FLOAT(dsttype)) { -#line 9222 - CError_FATAL(); + CError_FATAL(9222); return; } @@ -4816,14 +4762,12 @@ void I8_gen_TYPCON(ENode *expr, short outputReg, short outputRegHi, Operand *out if (TYPE_IS_8BYTES(expr->rtype) && dsttype->size == srctype->size) { coerce_to_register_pair(output, srctype, outputReg, outputRegHi); } else { -#line 9256 - CError_FATAL(); + CError_FATAL(9256); } return; } -#line 9261 - CError_FATAL(); + CError_FATAL(9261); } void gen_VECTOR128CONST(ENode *expr, short outputReg, short outputRegHi, Operand *output) { @@ -4832,10 +4776,8 @@ void gen_VECTOR128CONST(ENode *expr, short outputReg, short outputRegHi, Operand COVCResult result; vr = outputReg ? outputReg : ALLOC_VR(); - if (!canoptimizevectorconst(&expr->data.vector128val, expr->rtype, &result)) { -#line 9282 - CError_FATAL(); - } + if (!canoptimizevectorconst(&expr->data.vector128val, expr->rtype, &result)) + CError_FATAL(9282); if (result.op1 != -1) { emitpcode(result.op1, vr, result.arg); @@ -4853,6 +4795,5 @@ void gen_VECTOR128CONST(ENode *expr, short outputReg, short outputRegHi, Operand return; } -#line 9298 - CError_FATAL(); + CError_FATAL(9298); } diff --git a/compiler_and_linker/unsorted/IrOptimizer.c b/compiler_and_linker/unsorted/IrOptimizer.c index 462adf3..ae38df0 100644 --- a/compiler_and_linker/unsorted/IrOptimizer.c +++ b/compiler_and_linker/unsorted/IrOptimizer.c @@ -1,5 +1,26 @@ #include "compiler/IrOptimizer.h" +#include "compiler/CError.h" #include "compiler/CParser.h" +#include "compiler/InlineAsmPPC.h" +#include "compiler/IroCSE.h" +#include "compiler/IroDump.h" +#include "compiler/IroEval.h" +#include "compiler/IroFlowgraph.h" +#include "compiler/IroLinearForm.h" +#include "compiler/IroSubable.h" +#include "compiler/IroTransform.h" +#include "compiler/IROUseDef.h" +#include "compiler/IroUtil.h" +#include "compiler/IroVars.h" +#include "compiler/objects.h" +#include "compiler/IroPropagate.h" +#include "compiler/IroPointerAnalysis.h" +#include "compiler/IroJump.h" +#include "compiler/IroRangePropagation.h" +#include "compiler/IroEmptyLoop.h" +#include "compiler/IroUnrollLoop.h" +#include "compiler/IroLoop.h" +#include "compiler/IroExprRegeneration.h" Boolean DoScalarize; Boolean DoLinearize; @@ -9,37 +30,367 @@ Boolean VectorPhaseCalledFromUnroll; Boolean IRO_Log; static Boolean stIsSetup; -static void CountRefToObject() { +static void CountRefToObject(Object *object, int depth) { + static unsigned short LoopUsage[] = {1, 4, 16, 64}; + + if (depth > 3) + depth = 3; + + object->u.var.info->usage += LoopUsage[depth]; + object->u.var.info->used = 1; } -static void CountARef() { +static void CountARef(IROLinear *node, int depth) { + Object *object; + + object = node->u.node->data.objref; + CError_ASSERT(78, object->datatype != DALIAS); + + if (object->datatype == DLOCAL && object->u.var.info) { + CountRefToObject(object, depth); + if ((node->flags & IROLF_Used) && (node->flags & IROLF_Assigned)) + CountRefToObject(object, depth); + + if (!(node->flags & IROLF_Immind) && !object->u.var.info->noregister) + object->u.var.info->noregister = 2; + } } -static void CountDoubleInd() { +static void CountDoubleInd(IROLinear *node, int depth) { + if (IRO_IsVariable(node)) { + CountARef(node->u.monadic, depth); + } else if (node->type == IROLinearOp2Arg) { + if (node->nodetype == EADD) { + CountDoubleInd(node->u.diadic.left, depth); + CountDoubleInd(node->u.diadic.right, depth); + } else if (IRO_IsAddressMultiply(node)) { + if (IRO_IsVariable(node->u.diadic.left)) + CountARef(node->u.diadic.left->u.monadic, depth); + } + } } -static void CountUsage() { +static void CountUsage(void) { + IRONode *fnode = IRO_FirstNode; + IROLinear *node; + + if (IRO_FirstNode) { + for (; fnode; fnode = fnode->nextnode) { + for (node = fnode->first; node; node = node->next) { + if (IS_LINEAR_ENODE(node, EOBJREF)) + CountARef(node, fnode->loopdepth); + else if (IS_LINEAR_MONADIC(node, EINDIRECT)) + CountDoubleInd(node->u.monadic, fnode->loopdepth); + + if (node->type == IROLinearAsm) { + IAEffects effects; + int i; + + CodeGen_GetAsmEffects(node->u.asm_stmt, &effects); + for (i = 0; i < effects.numoperands; i++) { + Object *object = effects.operands[i].object; + if (object->datatype == DLOCAL && object->u.var.info) { + CountRefToObject(object, fnode->loopdepth); + if (effects.operands[i].type == IAOpnd_3 && !object->u.var.info->noregister) + object->u.var.info->noregister = 2; + } + } + } + + if (node == fnode->last) + break; + } + } + } else { + for (node = IRO_FirstLinear; node; node = node->next) { + if (IS_LINEAR_ENODE(node, EOBJREF)) + CountARef(node, 0); + else if (IS_LINEAR_MONADIC(node, EINDIRECT)) + CountDoubleInd(node->u.monadic, 0); + } + } + + IRO_CheckForUserBreak(); } -Statement *IRO_Optimizer(Object *obj, Statement *stmt) { +Statement *IRO_Optimizer(Object *func, Statement *statements) { + Boolean changed; + Boolean changed2; + int pass; + int passCount; + + CError_ASSERT(234, stIsSetup); + + DisableDueToAsm = 0; + FunctionName = func; + DoScalarize = 1; + DoLinearize = 1; + EarlyReturn = 0; + IRO_Depends = NULL; + LoopOptimizerRun = 0; + IRO_IsLeafFunction = 1; + IRO_FunctionHasReturn = 0; + + IRO_SetupForUserBreakChecking(); + + IRO_Dump("Starting function %s\n", func ? func->name->name : "Init-code"); + IRO_Dump("--------------------------------------------------------------------------------\n"); + + if (DoLinearize) + IRO_PreLinearize(statements); + if (copts.optimizationlevel > 0) + IRO_TransformTree(statements); + + VectorPhaseCalledFromUnroll = 0; + + IRO_Linearize(statements); + + CurStat = NULL; + + IRO_FirstExpr = NULL; + IRO_LastExpr = NULL; + IRO_FirstAssign = NULL; + IRO_LastAssign = NULL; + IRO_FirstVarUse = NULL; + IRO_LastVarUse = NULL; + IRO_FirstNode = NULL; + IRO_LastNode = NULL; + + if (copts.optimizationlevel > 0) + IRO_DoTransformations(); + + IRO_BuildFlowgraph(IRO_FirstLinear); + IRO_DumpAfterPhase("IRO_BuildflowGraph", 0); + + IRO_FindAllVars(); + IRO_CheckInit(); + + if (!DisableDueToAsm && copts.optimizationlevel > 0 && copts.opt_pointer_analysis && func) { + IRO_AnalyzePointers(func); + if (copts.opt_propagation && IRO_EvaluateDefinitePointers(func)) { + IRO_UpdateFlagsOnInts(); + IRO_UpdateVars(); + IRO_DumpAfterPhase("IRO_EvaluateDefinitePointers", 0); + } + } + + if (copts.optimizationlevel > 0) { + changed = IRO_EvaluateConditionals(); + + if (!DisableDueToAsm) { + changed |= IRO_RemoveUnreachable(); + IRO_DumpAfterPhase("IRO_RemoveUnreachable", 0); + } + + changed |= IRO_RemoveRedundantJumps(); + IRO_DumpAfterPhase("IRO_RemoveRedundantJumps", 0); + + if (!DisableDueToAsm) { + changed |= IRO_RemoveLabels(); + IRO_DumpAfterPhase("IRO_RemoveLabels()", 0); + } + + if (changed) { + IRO_BuildFlowgraph(IRO_FirstLinear); + IRO_DumpAfterPhase("IRO_BuildflowGraph--1", 0); + } + } + + if (!DisableDueToAsm && copts.optimizationlevel > 0) { + passCount = copts._B4 ? 2 : 1; + IRO_CPFirstTime = 1; + for (pass = 0; pass < passCount; pass++) { + IRO_Dump("*****************\n"); + IRO_Dump("Dumps for pass=%d\n", pass); + IRO_Dump("*****************\n"); + + if (DoScalarize) + IRO_ScalarizeClassDataMembers(); + IRO_DumpAfterPhase("IRO_ScalarizeClassDataMembers", 0); + + if (copts.opt_propagation) { + IRO_CopyAndConstantPropagation(); + IRO_CPFirstTime = 0; + IRO_ExpressionPropagation(); + IRO_DumpAfterPhase("Copy and constant propagation", 0); + + IRO_RangePropagateInFNode(); + IRO_DumpAfterPhase("IRO_RangePropagateInFNode", 0); + IRO_UpdateFlagsOnInts(); + } + + IRO_DumpAfterPhase("IRO_ExpressionPropagation", 0); + + if (copts.opt_dead_assignments || copts.opt_propagation) + IRO_UseDef(copts.opt_dead_assignments, copts.opt_propagation); + IRO_DumpAfterPhase("after IRO_UseDef", 0); + + IRO_UpdateVars(); + IRO_ConstantFolding(); + IRO_DumpAfterPhase("IRO_ConstantFolding", 0); + + IRO_EvaluateConditionals(); + IRO_RemoveUnreachable(); + IRO_SimplifyConditionals(); + + if (pass == 1 && copts.optimizationlevel > 2) { + IRO_RenumberInts(); + IRO_DumpAfterPhase("Before IRO_FindEmptyLoops", 0); + IRO_FindEmptyLoops(); + IRO_DumpAfterPhase("After IRO_FindEmptyLoops", 0); + IRO_RenumberInts(); + } + + if (copts.opt_unroll_loops && !copts.optimize_for_size && pass == 0) { + IRO_DumpAfterPhase("Before IRO_LoopUnroller", 0); + IRO_LoopUnroller(); + IRO_DumpAfterPhase("After IRO_LoopUnroller", 0); + IRO_RenumberInts(); + } + + VectorPhaseCalledFromUnroll = 0; + + if (pass == 0 && (copts.opt_loop_invariants || copts.opt_strength_reduction)) { + IRO_DumpAfterPhase("Before IRO_FindLoops", 0); + IRO_FindLoops(); + LoopOptimizerRun = 1; + IRO_SetLoopDepth(); + } + IRO_DumpAfterPhase("After IRO_FindLoops", 0); + + if (copts.opt_propagation) { + IRO_CopyAndConstantPropagation(); + IRO_ConstantFolding(); + IRO_EvaluateConditionals(); + } + + IRO_DumpAfterPhase("Second pass:IRO_CopyAndConstantPropagation, IRO_ConstantFolding, IRO_EvaluateConditionals", 0); + + if (copts.opt_common_subs) + IRO_FindExpressions(NULL, 0); + + if (copts.opt_common_subs) { + IRO_ComputeAvail(); + IRO_CommonSubs(); + } + IRO_DumpAfterPhase("IRO_CommonSubs", 0); + + IRO_UpdateFlagsOnInts(); + IRO_UpdateVars(); + IRO_DoTransformations(); + IRO_ConstantFolding(); + + do { + IRO_UpdateFlagsOnInts(); + + if (copts.opt_dead_code) + IRO_RemoveUnreachable(); + IRO_DumpAfterPhase("IRO_RemoveUnreachable", 0); + + changed2 = IRO_RemoveRedundantJumps(); + IRO_DumpAfterPhase("IRO_RemoveRedundantJumps", 0); + + changed2 |= IRO_RemoveLabels(); + IRO_DumpAfterPhase("IRO_RemoveLabels", 0); + + changed2 |= IRO_DoJumpChaining(); + IRO_DumpAfterPhase("IRO_DoJumpChaining", 0); + + if (copts.opt_propagation) { + IRO_RenumberInts(); + IRO_DumpAfterPhase("Before IRO_CopyAndConstantPropagation", 0); + changed2 |= IRO_CopyAndConstantPropagation(); + IRO_DumpAfterPhase("After IRO_CopyAndConstantPropagation", 0); + IRO_ConstantFolding(); + } + + if (copts.opt_dead_assignments || copts.opt_propagation) + changed2 |= IRO_UseDef(copts.opt_dead_assignments, copts.opt_propagation); + IRO_DumpAfterPhase("IRO_UseDef", 0); + + changed2 |= IRO_EvaluateConditionals(); + IRO_DumpAfterPhase("IRO_EvaluateConditionals", 0); + } while (changed2); + } + + if (copts.opt_lifetimes) { + IRO_UseDef(0, 0); + IRO_SplitLifetimes(); + } + + IRO_DoTransformations(); + IRO_DumpAfterPhase("Before RebuildCondExpressions", 0); + } + + IRO_RenumberInts(); + IRO_DumpAfterPhase("before IRO_RewriteBitFieldTemps", 0); + IRO_RewriteBitFieldTemps(); + IRO_DumpAfterPhase("After IRO_RewriteBitFieldTemps", 0); + + CountUsage(); + + if (!DisableDueToAsm) { + IRO_RegenerateExpressions(); + IRO_DumpAfterPhase("IRO_RegenerateExpressions", 0); + } + + IRO_DumpAfterPhase("After IRO_Optimizer", 0); + + statements = IRO_Delinearize(IRO_FirstNode, NULL); + + IRO_ZapVarPtrs(); + freeoheap(); + return statements; } void IRO_Setup(void) { static Boolean ENodeArraysHaveBeenInitialized; + + if (!stIsSetup) { + IRO_Log = 0; + IRO_SetupDump(); + if (!ENodeArraysHaveBeenInitialized) { + IRO_InitializeNodeNamesArray(); + IRO_InitializeIsAssociativeENodeTypeArray(); + IRO_InitializeIsSubableOpArray(); + IRO_InitializeAssignmentOpArray(); + IRO_InitializeComplementaryOpArray(); + IRO_InitializeComplementaryOpLogicalArray(); + IRO_InitializeNonAssignmentOpArray(); + IRO_InitializeAssignmentFoldingFunctionArray(); + IRO_InitializeIRO_IsModifyOpArray(); + IRO_InitializeIRO_IsAssignOpArray(); + ENodeArraysHaveBeenInitialized = 1; + } + stIsSetup = 1; + } } void IRO_Cleanup(void) { + if (stIsSetup) { + IRO_CleanupDump(); + stIsSetup = 0; + } } void CodeGen_UpdateOptimizerOptions(void) { - copts.opt_dead_code = copts.optimizationlevel > 0; - copts.opt_propagation = copts.optimizationlevel > 1; - copts.opt_common_subs = copts.optimizationlevel > 1; - copts.opt_vectorize_loops = copts.optimizationlevel > 2; - copts.opt_unroll_loops = copts.optimizationlevel > 2; - copts.opt_dead_assignments = copts.optimizationlevel > 2; - copts.opt_lifetimes = copts.optimizationlevel > 2; - copts.opt_strength_reduction = copts.optimizationlevel > 2; - copts.opt_loop_invariants = copts.optimizationlevel > 2; - copts._B4 = copts.optimizationlevel > 3; + Boolean flag; + + flag = copts.optimizationlevel >= 1; + copts.opt_dead_code = flag; + + flag = copts.optimizationlevel >= 2; + copts.opt_propagation = flag; + copts.opt_common_subs = flag; + + flag = copts.optimizationlevel >= 3; + copts.opt_vectorize_loops = flag; + copts.opt_unroll_loops = flag; + copts.opt_dead_assignments = flag; + copts.opt_lifetimes = flag; + copts.opt_strength_reduction = flag; + copts.opt_loop_invariants = flag; + + flag = copts.optimizationlevel >= 4; + copts._B4 = flag; } diff --git a/compiler_and_linker/unsorted/IroCSE.c b/compiler_and_linker/unsorted/IroCSE.c index dd82716..2311786 100644 --- a/compiler_and_linker/unsorted/IroCSE.c +++ b/compiler_and_linker/unsorted/IroCSE.c @@ -5,6 +5,7 @@ #include "compiler/IroMalloc.h" #include "compiler/IroPointerAnalysis.h" #include "compiler/IroSubable.h" +#include "compiler/IROUseDef.h" #include "compiler/IroUtil.h" #include "compiler/IroVars.h" #include "compiler/CError.h" @@ -979,10 +980,22 @@ void IRO_CommonSubs(void) { IRO_CheckForUserBreak(); } -static Boolean CountThisSubableOperandUse() { +static Boolean CountThisSubableOperandUse(IROUse *use) { + return use->x1C != 0; } -static void GetSubableOperandUseCount() { +static int GetSubableOperandUseCount(VarRecord *var) { + int count = 0; + IROUse *use; + + if (var->uses) { + for (use = var->uses; use; use = use->varnext) { + if (CountThisSubableOperandUse(use)) + count++; + } + } + + return count; } static void IRO_MakeTopLevelExprForSubableOperand(IROLinear *linear) { diff --git a/compiler_and_linker/unsorted/IroEval.c b/compiler_and_linker/unsorted/IroEval.c index e69de29..a34cf89 100644 --- a/compiler_and_linker/unsorted/IroEval.c +++ b/compiler_and_linker/unsorted/IroEval.c @@ -0,0 +1,914 @@ +#include "compiler/IroEval.h" +#include "compiler/CInt64.h" +#include "compiler/CMachine.h" +#include "compiler/CParser.h" +#include "compiler/IroFlowgraph.h" +#include "compiler/IroLinearForm.h" +#include "compiler/IroMalloc.h" +#include "compiler/IroPointerAnalysis.h" +#include "compiler/IroUtil.h" +#include "compiler/IroVars.h" +#include "compiler/enode.h" +#include "compiler/objects.h" +#include "compiler/types.h" + +static Boolean IsAssociativeENodeType[MAXEXPR]; + +void IRO_InitializeIsAssociativeENodeTypeArray(void) { + int i; + + for (i = 0; i < MAXEXPR; i++) + IsAssociativeENodeType[i] = 0; + + IsAssociativeENodeType[EPOSTINC] = 0; + IsAssociativeENodeType[EPOSTDEC] = 0; + IsAssociativeENodeType[EPREINC] = 0; + IsAssociativeENodeType[EPREDEC] = 0; + IsAssociativeENodeType[EINDIRECT] = 0; + IsAssociativeENodeType[EMONMIN] = 0; + IsAssociativeENodeType[EBINNOT] = 0; + IsAssociativeENodeType[ELOGNOT] = 0; + IsAssociativeENodeType[EFORCELOAD] = 0; + IsAssociativeENodeType[EMUL] = 1; + IsAssociativeENodeType[EMULV] = 1; + IsAssociativeENodeType[EDIV] = 0; + IsAssociativeENodeType[EMODULO] = 0; + IsAssociativeENodeType[EADDV] = 1; + IsAssociativeENodeType[ESUBV] = 0; + IsAssociativeENodeType[EADD] = 1; + IsAssociativeENodeType[ESUB] = 0; + IsAssociativeENodeType[ESHL] = 0; + IsAssociativeENodeType[ESHR] = 0; + IsAssociativeENodeType[ELESS] = 0; + IsAssociativeENodeType[EGREATER] = 0; + IsAssociativeENodeType[ELESSEQU] = 0; + IsAssociativeENodeType[EGREATEREQU] = 0; + IsAssociativeENodeType[EEQU] = 0; + IsAssociativeENodeType[ENOTEQU] = 0; + IsAssociativeENodeType[EAND] = 1; + IsAssociativeENodeType[EXOR] = 1; + IsAssociativeENodeType[EOR] = 1; + IsAssociativeENodeType[ELAND] = 0; + IsAssociativeENodeType[ELOR] = 0; + IsAssociativeENodeType[EASS] = 0; + IsAssociativeENodeType[EMULASS] = 0; + IsAssociativeENodeType[EDIVASS] = 0; + IsAssociativeENodeType[EMODASS] = 0; + IsAssociativeENodeType[EADDASS] = 0; + IsAssociativeENodeType[ESUBASS] = 0; + IsAssociativeENodeType[ESHLASS] = 0; + IsAssociativeENodeType[ESHRASS] = 0; + IsAssociativeENodeType[EANDASS] = 0; + IsAssociativeENodeType[EXORASS] = 0; + IsAssociativeENodeType[EORASS] = 0; + IsAssociativeENodeType[ECOMMA] = 0; + IsAssociativeENodeType[EPMODULO] = 0; + IsAssociativeENodeType[EROTL] = 0; + IsAssociativeENodeType[EROTR] = 0; + IsAssociativeENodeType[EBCLR] = 0; + IsAssociativeENodeType[EBTST] = 0; + IsAssociativeENodeType[EBSET] = 0; + IsAssociativeENodeType[ETYPCON] = 0; + IsAssociativeENodeType[EBITFIELD] = 0; + IsAssociativeENodeType[EINTCONST] = 0; + IsAssociativeENodeType[EFLOATCONST] = 0; + IsAssociativeENodeType[ESTRINGCONST] = 0; + IsAssociativeENodeType[ECOND] = 0; + IsAssociativeENodeType[EFUNCCALL] = 0; + IsAssociativeENodeType[EFUNCCALLP] = 0; + IsAssociativeENodeType[EOBJREF] = 0; + IsAssociativeENodeType[EMFPOINTER] = 0; + IsAssociativeENodeType[ENULLCHECK] = 0; + IsAssociativeENodeType[EPRECOMP] = 0; + IsAssociativeENodeType[ETEMP] = 0; + IsAssociativeENodeType[EARGOBJ] = 0; + IsAssociativeENodeType[ELOCOBJ] = 0; + IsAssociativeENodeType[ELABEL] = 0; + IsAssociativeENodeType[ESETCONST] = 0; + IsAssociativeENodeType[ENEWEXCEPTION] = 0; + IsAssociativeENodeType[ENEWEXCEPTIONARRAY] = 0; + IsAssociativeENodeType[EOBJLIST] = 0; + IsAssociativeENodeType[EMEMBER] = 0; + IsAssociativeENodeType[ETEMPLDEP] = 0; + IsAssociativeENodeType[EINSTRUCTION] = 0; + IsAssociativeENodeType[EDEFINE] = 0; + IsAssociativeENodeType[EREUSE] = 0; + IsAssociativeENodeType[EASSBLK] = 0; + IsAssociativeENodeType[EVECTOR128CONST] = 0; + IsAssociativeENodeType[ECONDASS] = 0; +} + +void IRO_TruncateValueToType(CInt64 *val, Type *type) { + if (IRO_IsUnsignedType(type)) { + switch (type->size) { + case 1: + CInt64_ConvertUInt8(val); + break; + case 2: + CInt64_ConvertUInt16(val); + break; + case 4: + CInt64_ConvertUInt32(val); + break; + } + } else { + switch (type->size) { + case 1: + CInt64_ConvertInt8(val); + break; + case 2: + CInt64_ConvertInt16(val); + break; + case 4: + CInt64_ConvertInt32(val); + break; + } + } +} + +void IRO_TruncateBitfieldValueToType(CInt64 *val, Type *type, Type *type2) { + UInt32 limit; + UInt32 i; + UInt32 j; + CInt64 work; + + work = cint64_zero; + limit = TYPE_BITFIELD(type2)->unkB; + for (i = 0; i < limit; i++) + work = CInt64_Or(work, CInt64_Shl(cint64_one, IRO_MakeULong(i))); + *val = CInt64_And(*val, work); + + if (!IRO_IsUnsignedType(type)) { + work = cint64_zero; + for (j = 0; j <= (i - 1); j++) { + if (j == (i - 1)) + work = CInt64_Or(work, CInt64_Shl(cint64_one, IRO_MakeULong(j))); + } + if (CInt64_NotEqual(CInt64_And(work, *val), cint64_zero)) { + for (j = i - 1; j < 64; j++) + *val = CInt64_Or(*val, CInt64_Shl(cint64_one, IRO_MakeULong(j))); + } + } + + IRO_TruncateValueToType(val, type); +} + +void IRO_ConstantFolding(void) { + IROLinear *nd; + ENode *expr; + int isCompare; + int flag; + CInt64 val; + + for (nd = IRO_FirstLinear; nd; nd = nd->next) { + switch (nd->type) { + case IROLinearOp1Arg: + if (IRO_IsIntConstant(nd->u.monadic)) { + expr = NULL; + flag = 0; + val = nd->u.monadic->u.node->data.intval; + if (nd->nodetype == ETYPCON && IS_TYPE_FLOAT(nd->rtype)) { + expr = IRO_NewENode(EFLOATCONST); + if (!IRO_IsUnsignedType(nd->u.monadic->rtype)) + expr->data.floatval.value = CInt64_ConvertToLongDouble(&val); + else + expr->data.floatval.value = CInt64_ConvertUToLongDouble(&val); + expr->rtype = nd->rtype; + } else { + switch (nd->nodetype) { + case ETYPCON: + flag = 1; + break; + case ELOGNOT: + val = CInt64_Not(val); + flag = 1; + break; + case EBINNOT: + val = CInt64_Inv(val); + flag = 1; + break; + case EMONMIN: + val = CInt64_Neg(val); + flag = 1; + break; + } + + if (flag) { + IRO_TruncateValueToType(&val, nd->rtype); + expr = IRO_NewENode(EINTCONST); + expr->rtype = nd->rtype; + expr->data.intval = val; + } + } + + if (expr) { + nd->u.monadic->type = IROLinearNop; + nd->type = IROLinearOperand; + nd->u.node = expr; + } + } + break; + + case IROLinearOp2Arg: + if (IRO_IsIntConstant(nd->u.diadic.left) && !IRO_IsIntConstant(nd->u.diadic.right) && IsAssociativeENodeType[nd->nodetype]) { + IROLinear *tmp = nd->u.diadic.right; + nd->u.diadic.right = nd->u.diadic.left; + nd->u.diadic.left = tmp; + } + + if (IRO_IsIntConstant(nd->u.diadic.right) && nd->nodetype == ESUB) { + nd->nodetype = EADD; + if (IRO_IsIntConstant(nd->u.diadic.right)) { + CInt64 v; + v = CInt64_Neg(nd->u.diadic.right->u.node->data.intval); + nd->u.diadic.right->u.node->data.intval = v; + } else { + Float f; + f = CMach_CalcFloatMonadic( + nd->u.diadic.right->rtype, + '-', + nd->u.diadic.right->u.node->data.floatval); + nd->u.diadic.right->u.node->data.floatval = f; + } + } + + if ( + IRO_IsIntConstant(nd->u.diadic.right) && + IsAssociativeENodeType[nd->nodetype] && + nd->u.diadic.left->type == IROLinearOp2Arg && + nd->u.diadic.left->nodetype == nd->nodetype && + nd->u.diadic.left->rtype == nd->rtype && + IRO_IsIntConstant(nd->u.diadic.left->u.diadic.right) && + nd->u.diadic.left->u.diadic.right->rtype == nd->u.diadic.right->rtype + ) + { + IROLinear *tmp = nd->u.diadic.left; + nd->u.diadic.left = tmp->u.diadic.left; + tmp->u.diadic.left = tmp->u.diadic.right; + tmp->u.diadic.right = nd->u.diadic.right; + tmp->rtype = tmp->u.diadic.left->rtype; + nd->u.diadic.right = tmp; + nd = tmp; + } + + if (IRO_IsIntConstant(nd->u.diadic.left) && IRO_IsIntConstant(nd->u.diadic.right)) { + CInt64 val1 = nd->u.diadic.left->u.node->data.intval; + CInt64 val2 = nd->u.diadic.right->u.node->data.intval; + flag = 0; + switch (nd->nodetype) { + case EADD: + val = CInt64_Add(val1, val2); + flag = 1; + break; + case ESUB: + val = CInt64_Sub(val1, val2); + flag = 1; + break; + case EMUL: + if (IRO_IsUnsignedType(nd->rtype)) + val = CInt64_MulU(val1, val2); + else + val = CInt64_Mul(val1, val2); + flag = 1; + break; + case EDIV: + if (!CInt64_IsZero(&val2)) { + if (IRO_IsUnsignedType(nd->rtype)) + val = CInt64_DivU(val1, val2); + else + val = CInt64_Div(val1, val2); + flag = 1; + } + break; + case EMODULO: + if (!CInt64_IsZero(&val2)) { + if (IRO_IsUnsignedType(nd->rtype)) + val = CInt64_ModU(val1, val2); + else + val = CInt64_Mod(val1, val2); + flag = 1; + } + break; + case ESHL: + val = CInt64_Shl(val1, val2); + flag = 1; + break; + case ESHR: + if (IRO_IsUnsignedType(nd->rtype)) + val = CInt64_ShrU(val1, val2); + else + val = CInt64_Shr(val1, val2); + flag = 1; + break; + case EAND: + val = CInt64_And(val1, val2); + flag = 1; + break; + case EOR: + val = CInt64_Or(val1, val2); + flag = 1; + break; + case EXOR: + val = CInt64_Xor(val1, val2); + flag = 1; + break; + case ELESS: + if (IRO_IsUnsignedType(nd->u.diadic.left->rtype)) + CInt64_SetULong(&val, CInt64_LessU(val1, val2)); + else + CInt64_SetULong(&val, CInt64_Less(val1, val2)); + flag = 1; + break; + case EGREATER: + if (IRO_IsUnsignedType(nd->u.diadic.left->rtype)) + CInt64_SetULong(&val, CInt64_GreaterU(val1, val2)); + else + CInt64_SetULong(&val, CInt64_Greater(val1, val2)); + flag = 1; + break; + case ELESSEQU: + if (IRO_IsUnsignedType(nd->u.diadic.left->rtype)) + CInt64_SetULong(&val, CInt64_LessEqualU(val1, val2)); + else + CInt64_SetULong(&val, CInt64_LessEqual(val1, val2)); + flag = 1; + break; + case EGREATEREQU: + if (IRO_IsUnsignedType(nd->u.diadic.left->rtype)) + CInt64_SetULong(&val, CInt64_GreaterEqualU(val1, val2)); + else + CInt64_SetULong(&val, CInt64_GreaterEqual(val1, val2)); + flag = 1; + break; + case EEQU: + CInt64_SetULong(&val, CInt64_Equal(val1, val2)); + flag = 1; + break; + case ENOTEQU: + CInt64_SetULong(&val, CInt64_NotEqual(val1, val2)); + flag = 1; + break; + } + + if (flag) { + IRO_TruncateValueToType(&val, nd->rtype); + expr = IRO_NewENode(EINTCONST); + expr->rtype = nd->rtype; + expr->data.intval = val; + nd->u.diadic.left->type = IROLinearNop; + nd->u.diadic.right->type = IROLinearNop; + nd->type = IROLinearOperand; + nd->u.node = expr; + } + } + + if (IRO_IsFloatConstant(nd->u.diadic.left) && IRO_IsFloatConstant(nd->u.diadic.right)) { + Float fval1 = nd->u.diadic.left->u.node->data.floatval; + Float fval2 = nd->u.diadic.right->u.node->data.floatval; + Float fval; + flag = 0; + isCompare = 0; + switch (nd->nodetype) { + case EADD: + fval = CMach_CalcFloatDiadic(nd->rtype, fval1, '+', fval2); + flag = 1; + break; + case ESUB: + fval = CMach_CalcFloatDiadic(nd->rtype, fval1, '-', fval2); + flag = 1; + break; + case EMUL: + fval = CMach_CalcFloatDiadic(nd->rtype, fval1, '*', fval2); + flag = 1; + break; + case EDIV: + fval = CMach_CalcFloatDiadic(nd->rtype, fval1, '/', fval2); + flag = 1; + break; + case ELESS: + CInt64_SetULong(&val, CMach_CalcFloatDiadicBool(nd->rtype, fval1, '<', fval2)); + flag = 1; + isCompare = 1; + break; + case EGREATER: + CInt64_SetULong(&val, CMach_CalcFloatDiadicBool(nd->rtype, fval1, '>', fval2)); + flag = 1; + isCompare = 1; + break; + case ELESSEQU: + CInt64_SetULong(&val, CMach_CalcFloatDiadicBool(nd->rtype, fval1, TK_LESS_EQUAL, fval2)); + flag = 1; + isCompare = 1; + break; + case EGREATEREQU: + CInt64_SetULong(&val, CMach_CalcFloatDiadicBool(nd->rtype, fval1, TK_GREATER_EQUAL, fval2)); + flag = 1; + isCompare = 1; + break; + case EEQU: + CInt64_SetULong(&val, CMach_CalcFloatDiadicBool(nd->rtype, fval1, TK_LOGICAL_EQ, fval2)); + flag = 1; + isCompare = 1; + break; + case ENOTEQU: + CInt64_SetULong(&val, CMach_CalcFloatDiadicBool(nd->rtype, fval1, TK_LOGICAL_NE, fval2)); + flag = 1; + isCompare = 1; + break; + } + + if (flag) { + if (isCompare) { + IRO_TruncateValueToType(&val, nd->rtype); + expr = IRO_NewENode(EINTCONST); + expr->rtype = nd->rtype; + expr->data.intval = val; + nd->u.diadic.left->type = IROLinearNop; + nd->u.diadic.right->type = IROLinearNop; + nd->type = IROLinearOperand; + nd->u.node = expr; + } else { + expr = IRO_NewENode(EFLOATCONST); + expr->rtype = nd->rtype; + expr->data.floatval = fval; + nd->u.diadic.left->type = IROLinearNop; + nd->u.diadic.right->type = IROLinearNop; + nd->type = IROLinearOperand; + nd->u.node = expr; + } + } + } + + break; + } + } + + IRO_CheckForUserBreak(); +} + +Boolean IRO_EvaluateConditionals(void) { + IRONode *fnode; + IROLinear *nd; + Boolean changed = 0; + SwitchInfo *switchInfo; + SwitchCase *swcase; + char found; + CInt64 val; + + for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) { + nd = fnode->last; + switch (nd->type) { + case IROLinearIf: + case IROLinearIfNot: + if (IRO_IsIntConstant(nd->u.label.x4)) { + Boolean isZero = CInt64_IsZero(&nd->u.label.x4->u.node->data.intval); + IRO_NopOut(nd->u.label.x4); + if ((isZero == 0) == (nd->type == IROLinearIf)) + nd->type = IROLinearGoto; + else + nd->type = IROLinearNop; + changed = 1; + } + break; + + case IROLinearSwitch: + if (IRO_IsIntConstant(nd->u.swtch.x4)) { + val = nd->u.swtch.x4->u.node->data.intval; + switchInfo = nd->u.swtch.info; + swcase = switchInfo->cases; + + IRO_NopOut(nd->u.swtch.x4); + nd->type = IROLinearGoto; + + found = 0; + while (swcase) { + if (CInt64_GreaterEqual(val, swcase->min) && CInt64_LessEqual(val, swcase->max)) { + found = 1; + nd->u.label.label = swcase->label; + break; + } + swcase = swcase->next; + } + + if (!found) + nd->u.label.label = switchInfo->defaultlabel; + changed = 1; + } + break; + } + } + + if (changed) { + IRO_ComputeSuccPred(); + IRO_ComputeDom(); + } + IRO_CheckForUserBreak(); + + return changed; +} + +static int EEquConst(IROLinear *nd) { + return nd && (nd->nodetype == EEQU) && IRO_IsIntConstant(nd->u.diadic.right); +} + +static Object *VEquConst(IROLinear *nd) { + if (EEquConst(nd)) + return IRO_IsVariable(nd->u.diadic.left); + else + return NULL; +} + +static int IsConsecutive(CInt64 a, CInt64 b) { + CInt64 diff; + + if (!CInt64_Equal(a, cint64_min) && !CInt64_Equal(b, cint64_min)) { + diff = CInt64_Sub(b, a); + return CInt64_Equal(diff, cint64_one) || CInt64_Equal(diff, cint64_negone); + } + + return 0; +} + +static IROLinear *findLabel(CLabel *label) { + IROLinear *nd; + + for (nd = IRO_FirstLinear; nd; nd = nd->next) { + if (nd->type == IROLinearLabel && nd->u.label.label == label) + break; + } + + return nd; +} + +static IROLinear *leftLeaveOf(IROLinear *nd) { + switch (nd->type) { + case IROLinearOp1Arg: + return leftLeaveOf(nd->u.monadic); + case IROLinearOp2Arg: + return leftLeaveOf(nd->u.diadic.left); + case IROLinearOperand: + return nd; + default: + return NULL; + } +} + +static int checkNode(IRONode *fnode) { + IROLinear *nd; + + if (fnode->numpred <= 1) { + nd = fnode->first; + while (nd != fnode->last && (nd->type == IROLinearNop || nd->type == IROLinearLabel)) + nd = nd->next; + + if (nd == leftLeaveOf(fnode->last->u.label.x4)) + return 1; + } + + return 0; +} + +static int checkLabel(CLabel *label, IRONode *fnode) { + switch (fnode->last->type) { + case IROLinearIf: + if (label == fnode->last->u.label.label) + return 1; + break; + } + + return 0; +} + +static Object *checkExpr(Object *a, IROLinear *nd) { + Object *b = VEquConst(nd); + + if ((!a || a == b) && !IRO_HasSideEffect(nd)) + return b; + + return NULL; +} + +static int checkStruct(IRONode *fnode1, IRONode *fnode2) { + CLabel *label; + Object *var; + + if (fnode1 == fnode2) + return (int) checkExpr(NULL, fnode1->last->u.label.x4); + + label = fnode1->last->u.label.label; + var = IRO_IsVariable(fnode1->last->u.label.x4->u.monadic); + return checkNode(fnode2) && checkLabel(label, fnode2) && checkExpr(var, fnode2->last->u.label.x4); +} + +typedef struct ReduceInfo { + int x0; + int x4; + Object *x8; + IRONode *fnode; + struct ReduceInfo *next; + CInt64 val; +} ReduceInfo; + +static int MarkPattern1(ReduceInfo *info1, ReduceInfo *info2, CInt64 *val) { + ReduceInfo *scan; + + if (!info2) + return 0; + + if (info2->x0) + return MarkPattern1(info1, info2->next, val); + + for (scan = info1; scan; scan = scan->next) { + if (scan->x0 == 2) { + if (CInt64_Equal(info2->val, scan->val)) { + IRO_NopOut(scan->fnode->last); + IRO_NopOut(scan->fnode->last->u.label.x4); // right union? + scan->x0 = -1; + return MarkPattern1(info1, info2->next, val); + } + + if (IsConsecutive(info2->val, scan->val)) { + info2->x0 = 2; + if (CInt64_Greater(*val, scan->val)) + *val = scan->val; + if (CInt64_Greater(*val, info2->val)) + *val = info2->val; + MarkPattern1(scan->next, info2, val); + MarkPattern1(info1, info1->next, val); + return 1; + } + } + } + + return MarkPattern1(info1, info2->next, val); +} + +static int DoReducible1(ReduceInfo *info, CInt64 val) { + ReduceInfo *last; + ReduceInfo *scan; + IROLinear *right; + IROLinear *left; + IROLinear *typconRight; + IROLinear *typconLeft; + IROLinear *cond; + int count; + + count = 0; + for (scan = info; scan; scan = scan->next) { + if (scan->x0 == 2) { + last = scan; + count++; + } + } + + if (!count) + return 0; + + for (scan = info; scan != last; scan = scan->next) { + if (scan->x0 == 2) { + scan->x0 = -1; + IRO_NopOut(scan->fnode->last); + IRO_NopOut(scan->fnode->last->u.label.x4); + } + } + + last->x0 = -1; + + cond = last->fnode->last; + cond->u.label.x4->nodetype = ELESSEQU; + CInt64_SetULong(&cond->u.label.x4->u.diadic.right->u.node->data.intval, count - 1); + + typconLeft = IRO_NewLinear(IROLinearOp1Arg); + typconLeft->nodetype = ETYPCON; + typconLeft->rtype = IRO_UnsignedType(cond->u.label.x4->u.diadic.left->rtype); + typconLeft->index = ++IRO_NumLinear; + + typconRight = IRO_NewLinear(IROLinearOp1Arg); + *typconRight = *typconLeft; + typconRight->index = ++IRO_NumLinear; + + left = IRO_NewLinear(IROLinearOp2Arg); + left->nodetype = EADD; + left->rtype = cond->u.label.x4->u.diadic.left->rtype; + left->index = ++IRO_NumLinear; + + right = IRO_NewLinear(IROLinearOperand); + right->nodetype = EINTCONST; + right->rtype = cond->u.label.x4->u.diadic.left->rtype; + right->index = ++IRO_NumLinear; + right->u.node = IRO_NewENode(EINTCONST); + right->u.node->data.intval = CInt64_Neg(val); + right->u.node->rtype = right->rtype; + + typconLeft->next = cond->u.label.x4->u.diadic.left->next; + cond->u.label.x4->u.diadic.left->next = right; + right->next = left; + left->next = typconLeft; + + typconRight->next = cond->u.label.x4->u.diadic.right->next; + cond->u.label.x4->u.diadic.right->next = typconRight; + + typconLeft->u.monadic = left; + left->u.diadic.left = cond->u.label.x4->u.diadic.left; + left->u.diadic.right = right; + cond->u.label.x4->u.diadic.left = typconLeft; + typconRight->u.monadic = cond->u.label.x4->u.diadic.right; + cond->u.label.x4->u.diadic.right = typconRight; + + return count; +}; + +static int ReducePattern1(IRONode *startnode, IRONode *endnode) { + ReduceInfo *infos; + ReduceInfo *info; + int changed = 0; + int count; + IRONode *fnode; + int i; + int j; + CInt64 val; + + if (startnode == endnode) + return 0; + + count = 0; + for (fnode = startnode; fnode != endnode; fnode = fnode->nextnode) + count++; + + infos = oalloc(sizeof(ReduceInfo) * ++count); + + fnode = startnode; + for (i = 0; i < count; i++) { + infos[i].x0 = 0; + infos[i].x4 = 0; + infos[i].fnode = fnode; + infos[i].next = NULL; + infos[i].x8 = VEquConst(fnode->last->u.label.x4); + if (infos[i].x8) { + infos[i].val = fnode->last->u.label.x4->u.diadic.right->u.node->data.intval; + infos[i].x4 = 1; + } + fnode = fnode->nextnode; + } + + for (j = 0; j < count; j++) { + if (infos[j].x4 == 1 && infos[j].x8) { + infos[j].x4 = -1; + info = &infos[j]; + for (i = j + 1; i < count; i++) { + if (infos[j].x8 == infos[i].x8) { + info->next = &infos[i]; + info = &infos[i]; + infos[i].x4 = 0; + } + } + } + } + + for (j = 0; j < count; j++) { + if (infos[j].x4 == -1) { + for (info = &infos[j]; info; info = info->next) { + if (info->x0 == 0) { + info->x0 = 2; + val = info->val; + if (MarkPattern1(&infos[j], info->next, &val)) { + changed = 1; + DoReducible1(&infos[j], val); + } else { + info->x0 = -1; + } + } + } + } + } + + return changed; +} + +static int ReduceConsecutiveIf(IRONode *startnode, IRONode *endnode) { + IRONode *node31; + IRONode *node30; + int changed = 0; + + while (startnode != endnode) { + if (checkStruct(startnode, startnode)) + break; + startnode = startnode->nextnode; + } + + node31 = startnode; + if (startnode != endnode) { + node30 = startnode; + node31 = startnode->nextnode; + while (node31 != endnode) { + if (checkStruct(startnode, node31)) { + node30 = node31; + node31 = node31->nextnode; + } else { + node31 = node30; + break; + } + } + + if (node31 == endnode && !checkStruct(startnode, node31)) + node31 = node30; + + if (startnode != node31 && ReducePattern1(startnode, node31)) + changed = 1; + + if (node31 != endnode) + node31 = node31->nextnode; + } + + if (node31 != endnode && ReduceConsecutiveIf(node31, endnode)) + changed = 1; + + return changed; +} + +int IRO_SimplifyConditionals(void) { + IRONode *fnode; + IRONode *start; + IRONode *end; + int changed = 0; + + for (fnode = IRO_FirstNode; fnode; fnode = fnode->nextnode) { + if (fnode->last->type == IROLinearIf) { + start = end = fnode; + while (fnode->nextnode && fnode->nextnode->last->type == IROLinearIf) { + end = fnode = fnode->nextnode; + } + if (start != end && ReduceConsecutiveIf(start, end)) + changed = 1; + } + } + + if (changed) { + IRO_ComputeSuccPred(); + IRO_ComputeDom(); + } + IRO_CheckForUserBreak(); + return changed; +} + +Boolean IRO_EvaluateDefinitePointers(Object *func) { + IROLinear *nd; + Boolean result; // r29 + Boolean changed; // r28 + Boolean changed2; // r26 + IROLinear *nd2; // r25 + IROListNode *scan; // r25 + IROListNode *list; + + if (!copts.opt_pointer_analysis) + return 0; + + result = 0; + + do { + changed = 0; + + for (nd = IRO_FirstLinear; nd; nd = nd->next) { + if ( + nd->type == IROLinearOp1Arg && + nd->nodetype == EINDIRECT && + !(nd->flags & IROLF_Assigned) && + nd->pointsToFunction && + !IRO_HasSideEffect(nd) && + PointerAnalysis_IsLinearNodePointerExprDefinite(func, nd) + ) + { + list = NULL; + PointerAnalysis_LookupLinearNodePointerExpr(func, nd, &list); + if (list) { + if (list->list.head && list->list.tail && !list->nextList) { + changed2 = IRO_LocateFather_Cut_And_Paste(nd, list->list.tail) != NULL; + if (changed2) { + IRO_PasteAfter(list->list.head, list->list.tail, nd); + for (nd2 = list->list.head; nd2 != list->list.tail->next; nd2 = nd2->next) { + if (nd2->type == IROLinearOperand && nd2->u.node->type == EOBJREF) { + if (nd2->u.node->data.objref->datatype == DDATA || nd2->u.node->data.objref->datatype == DLOCAL) + IRO_FindVar(nd2->u.node->data.objref, 1, 1); + else + nd2->u.node->data.objref->varptr = NULL; + } + } + } + changed |= changed2; + } + + while (list) { + scan = list->nextList; + IRO_free(list); + list = scan; + } + } + } + } + + result |= changed; + IRO_CheckForUserBreak(); + } while (changed); + + return result; +} diff --git a/compiler_and_linker/unsorted/IroFlowgraph.c b/compiler_and_linker/unsorted/IroFlowgraph.c index f9a18fd..5c9c840 100644 --- a/compiler_and_linker/unsorted/IroFlowgraph.c +++ b/compiler_and_linker/unsorted/IroFlowgraph.c @@ -331,5 +331,109 @@ IRONode *IRO_NewFlowGraphNode(void) { } IRONode *IRO_MergeFlowGraphNodes(IRONode *a, IRONode *b) { - // TODO + IRONode *succ; + Boolean found; + UInt32 i; + UInt32 j; + UInt32 k; + + if (a->nextnode == b && a->last && b->first && a->last->next == b->first) { + if (b->first->type == IROLinearLabel) + IRO_NopOut(b->first); + + a->nextnode = b->nextnode; + a->last = b->last; + + for (i = 0; i < a->numsucc; i++) { + if (b->index == a->succ[i]) { + for (j = i; j < a->numsucc; j++) { + if ((j + 1) < a->numsucc) + a->succ[j] = a->succ[j + 1]; + else + a->succ[j] = 0; + } + a->numsucc--; + break; + } + } + + for (i = 0; i < b->numsucc; i++) { + succ = IRO_NodeTable[b->succ[i]]; + for (j = 0; j < a->numsucc; j++) { + if (b->succ[i] == a->succ[j]) + break; + } + + if (j == a->numsucc) { + AddSucc(a, IRO_NodeTable[b->succ[i]]); + succ->numpred--; + } + + found = 0; + for (j = 0; j < succ->numpred; j++) { + if (a->index == succ->pred[j]) { + found = 1; + break; + } + } + + for (j = 0; j < succ->numpred; j++) { + if (b->index == succ->pred[j]) { + if (!found) { + succ->pred[j] = a->index; + } else { + for (k = j; k < succ->numpred; k++) { + if ((k + 1) < succ->numpred) + succ->pred[k] = succ->pred[k + 1]; + else + succ->pred[k] = 0; + } + succ->numpred--; + } + break; + } + } + } + + b->numsucc = b->numpred = 0; + b->first = b->last = NULL; + b->nextnode = NULL; + b->x36 = 0; + b->x37 = 0; + b->mustreach = 0; + b->x39 = 0; + b->loopdepth = 0; + + if (IRO_LastNode == b) + IRO_LastNode = a; + + if (IRO_FirstExpr && IRO_LastExpr) { + IROExpr *expr; + for (expr = IRO_FirstExpr; expr && expr != IRO_LastExpr->next; expr = expr->next) { + if (expr->node == b) + expr->node = a; + } + } + + if (IRO_FirstAssign && IRO_LastAssign) { + IROAssign *assign; + for (assign = IRO_FirstAssign; assign && assign != IRO_LastAssign->next; assign = assign->next) { + if (assign->node == b) + assign->node = a; + } + } + + if (IRO_FirstVarUse && IRO_LastVarUse) { + IROUse *use; + for (use = IRO_FirstVarUse; use && use != IRO_LastVarUse->globalnext; use = use->globalnext) { + if (use->node == b) + use->node = a; + } + } + + IRO_NodeTable[b->index] = NULL; + return a; + } + + return NULL; } diff --git a/compiler_and_linker/unsorted/IroLoop.c b/compiler_and_linker/unsorted/IroLoop.c index 01391bd..8a7f4fe 100644 --- a/compiler_and_linker/unsorted/IroLoop.c +++ b/compiler_and_linker/unsorted/IroLoop.c @@ -1902,7 +1902,7 @@ IROLoop *ExtractLoopInfo(IRONode *fnode) { if (IS_LINEAR_DIADIC_2(loop->nd18, ELESS, ELESSEQU)) { if (nd21->nodetype == EADDASS) { if (scanind->addConst == 1) - loop->flags |= LoopFlags_100; + loop->flags |= LP_LOOP_STEP_ISADD; if (scanind->addConst > 0) loop->flags |= LP_LOOP_STEP_ISPOS; } else if (nd21->nodetype == EASS && @@ -1910,7 +1910,7 @@ IROLoop *ExtractLoopInfo(IRONode *fnode) { IRO_IsIntConstant(tmp18 = nd21->u.diadic.right->u.diadic.right) && CTool_EndianReadWord32(&tmp18->u.node->data.intval.hi) == 0) { if (CInt64_GetULong(&tmp18->u.node->data.intval) == 1) - loop->flags |= LoopFlags_100; + loop->flags |= LP_LOOP_STEP_ISADD; if (CInt64_GetULong(&tmp18->u.node->data.intval) > 0) loop->flags |= LP_LOOP_STEP_ISPOS; } @@ -1918,7 +1918,7 @@ IROLoop *ExtractLoopInfo(IRONode *fnode) { } else if (nd21->type == IROLinearOp1Arg) { if (nd21->nodetype == EPREINC || nd21->nodetype == EPOSTINC) { if (scanind->addConst == 1) - loop->flags |= LoopFlags_100; + loop->flags |= LP_LOOP_STEP_ISADD; if (scanind->addConst > 0) loop->flags |= LP_LOOP_STEP_ISPOS; } @@ -1997,7 +1997,7 @@ IROLoop *ExtractLoopInfo(IRONode *fnode) { for (scanind = FirstInd; scanind; scanind = scanind->next) { if (scanind->var->object == obj) { IRO_Dump("Induction has DIV: %s\n", obj->name->name); - scanind->flags |= LoopInd_2; + scanind->flags |= LoopInd_HasDiv; } } } @@ -2008,7 +2008,7 @@ IROLoop *ExtractLoopInfo(IRONode *fnode) { for (scanind = FirstInd; scanind && obj; scanind = scanind->next) { if (scanind->var->object == obj) { IRO_Dump("Induction has MOD: %s\n", obj->name->name); - scanind->flags |= LoopInd_1; + scanind->flags |= LoopInd_HasMod; } } } diff --git a/compiler_and_linker/unsorted/IroPointerAnalysis.c b/compiler_and_linker/unsorted/IroPointerAnalysis.c index a47d544..0fb2498 100644 --- a/compiler_and_linker/unsorted/IroPointerAnalysis.c +++ b/compiler_and_linker/unsorted/IroPointerAnalysis.c @@ -43,9 +43,8 @@ static Boolean LocationIsVolatile(LocationSet *loc, Object *proc) { Boolean result; Type *rtype; -#line 932 - IRO_ASSERT(loc != NULL); - IRO_ASSERT(proc != NULL); + IRO_ASSERT(932, loc != NULL); + IRO_ASSERT(933, proc != NULL); result = 0; @@ -107,9 +106,8 @@ static Object *GetLocalObject(PALocalVar *local, Object *proc, Boolean flag) { Object *obj; char *name; -#line 999 - IRO_ASSERT(local != NULL); - IRO_ASSERT(proc != NULL); + IRO_ASSERT(999, local != NULL); + IRO_ASSERT(1000, proc != NULL); obj = PALocalVar_Get0_sub_4847E0(local); name = PALocalVar_Get4_sub_4847D0(local); @@ -131,8 +129,7 @@ static Object *GetLocalObject(PALocalVar *local, Object *proc, Boolean flag) { } static Boolean ObjectIsAnExtendedParamCandidate(Object *obj) { -#line 1042 - IRO_ASSERT(obj != NULL); + IRO_ASSERT(1042, obj != NULL); return Inline_IsObjectData(obj) || obj->datatype == DABSOLUTE || @@ -142,8 +139,7 @@ static Boolean ObjectIsAnExtendedParamCandidate(Object *obj) { } static Boolean ObjectIsAFunction(Object *obj) { -#line 1054 - IRO_ASSERT(obj != NULL); + IRO_ASSERT(1054, obj != NULL); return obj->datatype == DFUNC || obj->datatype == DVFUNC || @@ -157,18 +153,16 @@ static Boolean LocationSetRepresentsSingleLocation(LocationSet *ls, Object *proc ExtendedParam *ep; ObjectSet *objSet; -#line 1073 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(proc == NULL || proc != NULL); - IRO_ASSERT(pointsToFunc == NULL || pointsToFunc != NULL); + IRO_ASSERT(1073, ls != NULL); + IRO_ASSERT(1074, proc == NULL || proc != NULL); + IRO_ASSERT(1075, pointsToFunc == NULL || pointsToFunc != NULL); result = 1; if (LocationSet_IsUnknown(ls) || LocationSet_stride(ls)) { result = 0; } else { mb = LocationSet_block(ls); -#line 1084 - IRO_ASSERT(mb != NULL); + IRO_ASSERT(1084, mb != NULL); kind = PAMemoryBlock_kind(mb); if (kind == PAMEMORYBLOCKKIND_HEAPBLOCK) { @@ -217,10 +211,9 @@ static void EvalExprAction(LocationSet *ls, void *refcon) { UInt32 stride; PAMemoryBlock *mb; -#line 1151 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(!LocationSet_IsUnknown(ls)); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(1151, ls != NULL); + IRO_ASSERT(1152, !LocationSet_IsUnknown(ls)); + IRO_ASSERT(1153, refcon != NULL); value = *((CInt64 *) refcon); stride = LocationSet_stride(ls); @@ -247,10 +240,9 @@ static void EvalExprAction(LocationSet *ls, void *refcon) { static void EvalExprAction2(LocationSet *ls, void *refcon) { UInt32 value; -#line 1188 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(!LocationSet_IsUnknown(ls)); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(1188, ls != NULL); + IRO_ASSERT(1189, !LocationSet_IsUnknown(ls)); + IRO_ASSERT(1190, refcon != NULL); value = CInt64_GetULong((CInt64 *) refcon); if (value) { @@ -279,9 +271,8 @@ typedef struct EvalExprAction3Params { static void EvalExprAction3(LocationSet *ls, void *refcon) { EvalExprAction3Params *params; -#line 1219 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(1219, ls != NULL); + IRO_ASSERT(1220, refcon != NULL); params = refcon; @@ -302,9 +293,8 @@ static void EvalExprAction4(LocationSet *ls, void *refcon) { Type *type; PAMemoryBlock *mb; -#line 1235 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(1235, ls != NULL); + IRO_ASSERT(1236, refcon != NULL); type = refcon; @@ -340,12 +330,11 @@ static Boolean EvalExpr(LocationSetSet *set, Object *proc, IROLinear *Int, Stack EvalExprAction3Params params; IROLinear *originalInt; -#line 1284 - IRO_ASSERT(set == NULL || set != NULL); - IRO_ASSERT(proc != NULL); - IRO_ASSERT(Int != NULL); - IRO_ASSERT(map == NULL || map != NULL); - IRO_ASSERT(stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL); + IRO_ASSERT(1284, set == NULL || set != NULL); + IRO_ASSERT(1285, proc != NULL); + IRO_ASSERT(1286, Int != NULL); + IRO_ASSERT(1287, map == NULL || map != NULL); + IRO_ASSERT(1288, stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL); result = 0; lss = LocationSetSet_New(); @@ -355,16 +344,14 @@ static Boolean EvalExpr(LocationSetSet *set, Object *proc, IROLinear *Int, Stack while (Int && Int->type == IROLinearOp1Arg && Int->nodetype == ETYPCON) Int = Int->u.monadic; -#line 1302 - IRO_ASSERT(Int != NULL); + IRO_ASSERT(1302, Int != NULL); if (IRO_IsAssignment(Int)) { if (Int->type == IROLinearOp1Arg) indirect = Int->u.monadic; else indirect = Int->u.diadic.left; -#line 1310 - IRO_ASSERT(indirect->type == IROLinearOp1Arg && indirect->nodetype == EINDIRECT); + IRO_ASSERT(1310, indirect->type == IROLinearOp1Arg && indirect->nodetype == EINDIRECT); lss2 = LocationSetSet_New(); LocationSetSet_Init(lss2); @@ -387,8 +374,7 @@ static Boolean EvalExpr(LocationSetSet *set, Object *proc, IROLinear *Int, Stack LocationSetSet_Term(lss2); LocationSetSet_Delete(lss2); } else if (Int->type == IROLinearFunccall) { -#line 1338 - IRO_ASSERT(Int->u.funccall.returnedLocs != NULL); + IRO_ASSERT(1338, Int->u.funccall.returnedLocs != NULL); LocationSetSet_AddSet(lss, Int->u.funccall.returnedLocs); } else if (Int->type == IROLinearOp1Arg && Int->nodetype == EINDIRECT) { lss2 = LocationSetSet_New(); @@ -425,12 +411,10 @@ static Boolean EvalExpr(LocationSetSet *set, Object *proc, IROLinear *Int, Stack flag2 = 0; if (addr->numObjRefs == 1) { Object *obj; -#line 1383 - IRO_ASSERT(addr->objRefs->element->type == IROLinearOperand); - IRO_ASSERT(addr->objRefs->element->u.node->type == EOBJREF); + IRO_ASSERT(1383, addr->objRefs->element->type == IROLinearOperand); + IRO_ASSERT(1384, addr->objRefs->element->u.node->type == EOBJREF); obj = ((IROLinear *) addr->objRefs->element)->u.node->data.objref; -#line 1387 - IRO_ASSERT(obj != NULL); + IRO_ASSERT(1387, obj != NULL); result |= EvalExpr(lss, proc, addr->objRefs->element, stackPtr, map, ptf); flag2 = 1; } @@ -536,8 +520,7 @@ static Boolean EvalExpr(LocationSetSet *set, Object *proc, IROLinear *Int, Stack addend = list->element; if (addend) { -#line 1536 - IRO_ASSERT(IRO_IsIntConstant(addend)); + IRO_ASSERT(1536, IRO_IsIntConstant(addend)); value = CInt64_Add(value, addend->u.node->data.intval); } @@ -584,8 +567,7 @@ static Boolean EvalExpr(LocationSetSet *set, Object *proc, IROLinear *Int, Stack thing = Int->u.node; } else if (Int->u.node->type == EOBJREF) { obj = Int->u.node->data.objref; -#line 1597 - IRO_ASSERT(obj != NULL); + IRO_ASSERT(1597, obj != NULL); if (ObjectIsAnExtendedParamCandidate(obj)) { kind = PAMEMORYBLOCKKIND_EXTENDEDPARAM; thing = CreateExtendedParam(stackPtr, map, obj, &result); @@ -619,12 +601,10 @@ static Boolean EvalExpr(LocationSetSet *set, Object *proc, IROLinear *Int, Stack LocationSetSet_Init(lss2); result |= EvalExpr(lss2, proc, Int->u.monadic, stackPtr, map, ptf); - if (LocationSetSet_Count(lss2) == 1 && (ls = LocationSetSet_FindFirst(lss2))) { + if (LocationSetSet_Count(lss2) == 1 && (ls = LocationSetSet_FindFirst(lss2))) LocationSetSet_AddUnknown(lss, NULL, NULL, ls); - } else { -#line 1643 - CError_FATAL(); - } + else + CError_FATAL(1643); LocationSetSet_Term(lss2); LocationSetSet_Delete(lss2); @@ -706,11 +686,11 @@ static Boolean EvalENodeExpr(LocationSetSet *set, Object *proc, ENode *Int, Stac EvalExprAction3Params params; ENode *originalInt; - IRO_ASSERT(set == NULL || set != NULL); - IRO_ASSERT(proc != NULL); - IRO_ASSERT(Int != NULL); - IRO_ASSERT(map == NULL || map != NULL); - IRO_ASSERT(stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL); + IRO_ASSERT(0, set == NULL || set != NULL); + IRO_ASSERT(0, proc != NULL); + IRO_ASSERT(0, Int != NULL); + IRO_ASSERT(0, map == NULL || map != NULL); + IRO_ASSERT(0, stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL); result = 0; lss = LocationSetSet_New(); @@ -720,14 +700,14 @@ static Boolean EvalENodeExpr(LocationSetSet *set, Object *proc, ENode *Int, Stac while (Int && Int->type == ETYPCON) Int = Int->data.monadic; - IRO_ASSERT(Int != NULL); + IRO_ASSERT(0, Int != NULL); if (IRO_IsAssignOp[Int->type]) { if (Int->type == EPOSTINC || Int->type == EPOSTDEC || Int->type == EPREINC || Int->type == EPREDEC) indirect = Int->data.monadic; else indirect = Int->data.diadic.left; - IRO_ASSERT(indirect->type == EINDIRECT); + IRO_ASSERT(0, indirect->type == EINDIRECT); lss2 = LocationSetSet_New(); LocationSetSet_Init(lss2); @@ -787,7 +767,7 @@ static Boolean EvalENodeExpr(LocationSetSet *set, Object *proc, ENode *Int, Stac // IRO_ASSERT(addr->objRefs->element->type == IROLinearOperand); // IRO_ASSERT(addr->objRefs->element->u.node->type == EOBJREF); obj = ((ENode *) addr->objRefs->element)->data.objref; - IRO_ASSERT(obj != NULL); + IRO_ASSERT(0, obj != NULL); result |= EvalENodeExpr(lss, proc, addr->objRefs->element, stackPtr, map, ptf); flag2 = 1; } @@ -896,7 +876,7 @@ static Boolean EvalENodeExpr(LocationSetSet *set, Object *proc, ENode *Int, Stac addend = list->element; if (addend) { - IRO_ASSERT(addend->type == EINTCONST); + IRO_ASSERT(0, addend->type == EINTCONST); value = CInt64_Add(value, addend->data.intval); } @@ -943,7 +923,7 @@ static Boolean EvalENodeExpr(LocationSetSet *set, Object *proc, ENode *Int, Stac thing = Int; } else if (Int->type == EOBJREF) { obj = Int->data.objref; - IRO_ASSERT(obj != NULL); + IRO_ASSERT(0, obj != NULL); if (ObjectIsAnExtendedParamCandidate(obj)) { kind = PAMEMORYBLOCKKIND_EXTENDEDPARAM; thing = CreateExtendedParam(stackPtr, map, obj, &result); @@ -977,12 +957,10 @@ static Boolean EvalENodeExpr(LocationSetSet *set, Object *proc, ENode *Int, Stac LocationSetSet_Init(lss2); result |= EvalENodeExpr(lss2, proc, Int->data.monadic, stackPtr, map, ptf); - if (LocationSetSet_Count(lss2) == 1 && (ls = LocationSetSet_FindFirst(lss2))) { + if (LocationSetSet_Count(lss2) == 1 && (ls = LocationSetSet_FindFirst(lss2))) LocationSetSet_AddUnknown(lss, NULL, NULL, ls); - } else { -#line 2146 - CError_FATAL(); - } + else + CError_FATAL(2146); LocationSetSet_Term(lss2); LocationSetSet_Delete(lss2); @@ -1064,9 +1042,8 @@ static Boolean EvalVariable(LocationSetSet *set, Object *proc, VarRecord *var, P } static void StoreReturnedLocationsAction(LocationSet *loc, void *refcon) { -#line 2275 - IRO_ASSERT(loc != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(2275, loc != NULL); + IRO_ASSERT(2276, refcon != NULL); if (!LocationSet_IsUnknown(loc)) { if (PAMemoryBlock_kind(LocationSet_block(loc)) == PAMEMORYBLOCKKIND_HEAPBLOCK) { @@ -1095,11 +1072,10 @@ static void StoreReturnedLocations(IROLinear *nd, PartialTransferFunction *ptf, LocationSet *retLoc; LocationSetSet *retLocs; -#line 2307 - IRO_ASSERT(nd != NULL); - IRO_ASSERT(nd->type == IROLinearFunccall); - IRO_ASSERT(ptf != NULL); - IRO_ASSERT(map != NULL); + IRO_ASSERT(2307, nd != NULL); + IRO_ASSERT(2308, nd->type == IROLinearFunccall); + IRO_ASSERT(2309, ptf != NULL); + IRO_ASSERT(2310, map != NULL); retLoc = PartialTransferFunction_returnLocation(ptf); retLocs = nd->u.funccall.returnedLocs; @@ -1133,19 +1109,17 @@ static void FillInAppropriateMappingsWithExtParamAction(Object *obj, void *refco EPParams *params; ParamMapping *mapping; -#line 2352 - IRO_ASSERT(obj != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(2352, obj != NULL); + IRO_ASSERT(2353, refcon != NULL); params = refcon; -#line 2357 - IRO_ASSERT(params->map != NULL); - IRO_ASSERT(params->ep != NULL); - IRO_ASSERT(params->proc == NULL || params->proc != NULL); - IRO_ASSERT(params->proc != &stUnknown); - IRO_ASSERT(params->var == NULL || params->var != NULL); - IRO_ASSERT(params->var != &stUnknown); + IRO_ASSERT(2357, params->map != NULL); + IRO_ASSERT(2358, params->ep != NULL); + IRO_ASSERT(2359, params->proc == NULL || params->proc != NULL); + IRO_ASSERT(2360, params->proc != &stUnknown); + IRO_ASSERT(2361, params->var == NULL || params->var != NULL); + IRO_ASSERT(2362, params->var != &stUnknown); mapping = ParamMappingFunction_FindMappingByFormal(params->map, obj); if (!mapping) { @@ -1172,13 +1146,12 @@ static Boolean FillInAppropriateMappingsWithExtParam(ParamMappingFunction *map, EPParams params; ObjectSet *objSet; -#line 2398 - IRO_ASSERT(map != NULL); - IRO_ASSERT(var == NULL || var != NULL); - IRO_ASSERT(var != &stUnknown); - IRO_ASSERT(ep != NULL); - IRO_ASSERT(proc == NULL || proc != NULL); - IRO_ASSERT(proc != &stUnknown); + IRO_ASSERT(2398, map != NULL); + IRO_ASSERT(2399, var == NULL || var != NULL); + IRO_ASSERT(2400, var != &stUnknown); + IRO_ASSERT(2401, ep != NULL); + IRO_ASSERT(2402, proc == NULL || proc != NULL); + IRO_ASSERT(2403, proc != &stUnknown); memset(¶ms, 0, sizeof(params)); params.map = map; @@ -1205,24 +1178,20 @@ static void MatchPTFHelper(LocationSet *loc, LocationSetSet *locs, Object *proc, PAMemoryBlockKind kind; Object *obj; -#line 2448 - IRO_ASSERT(loc != NULL); - IRO_ASSERT(!LocationSet_IsUnknown(loc)); - IRO_ASSERT(locs != NULL); - IRO_ASSERT(proc != NULL); - IRO_ASSERT(map != NULL); - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(2448, loc != NULL); + IRO_ASSERT(2449, !LocationSet_IsUnknown(loc)); + IRO_ASSERT(2450, locs != NULL); + IRO_ASSERT(2451, proc != NULL); + IRO_ASSERT(2452, map != NULL); + IRO_ASSERT(2453, ptf != NULL); initial = PartialTransferFunction_initialPointsToFn(ptf); -#line 2456 - IRO_ASSERT(initial != NULL); + IRO_ASSERT(2456, initial != NULL); -#line 2458 - IRO_ASSERT(!LocationSet_IsUnknown(loc)); + IRO_ASSERT(2458, !LocationSet_IsUnknown(loc)); block = LocationSet_block(loc); -#line 2460 - IRO_ASSERT(block != NULL); + IRO_ASSERT(2460, block != NULL); kind = PAMemoryBlock_kind(block); @@ -1230,8 +1199,7 @@ static void MatchPTFHelper(LocationSet *loc, LocationSetSet *locs, Object *proc, PALocalVar *local; local = PAMemoryBlock_thing(block); -#line 2466 - IRO_ASSERT(local != NULL); + IRO_ASSERT(2466, local != NULL); obj = GetLocalObject(local, proc, 1); if (obj && ObjectIsAFunctionArgument(proc, obj)) { @@ -1255,16 +1223,14 @@ static void MatchPTFHelper(LocationSet *loc, LocationSetSet *locs, Object *proc, } } else if (kind == PAMEMORYBLOCKKIND_EXTENDEDPARAM) { void *ep = PAMemoryBlock_thing(block); -#line 2489 - IRO_ASSERT(ep != NULL); + IRO_ASSERT(2489, ep != NULL); obj = NULL; ObjectSet_ForEach(ExtendedParam_objectSet(ep), FindGlobalObjectAction, &obj); if (obj && obj != &stUnknown) FillInAppropriateMappingsWithExtParam(map, obj, ep, proc); } else { -#line 2500 - CError_FATAL(); + CError_FATAL(2500); } if (!PointsToFunction_FindByLookupCompatibleLocationSet(initial, loc)) { @@ -1296,16 +1262,14 @@ static void MatchPTFAction1(PointsToEntry *tgtPTE, void *refcon) { PAMemoryBlock *block; PAMemoryBlockKind kind; -#line 2525 - IRO_ASSERT(tgtPTE != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(2525, tgtPTE != NULL); + IRO_ASSERT(2526, refcon != NULL); params = refcon; -#line 2530 - IRO_ASSERT(params->proc != NULL); - IRO_ASSERT(params->ptfCopy != NULL); - IRO_ASSERT(params->mapCopy != NULL); + IRO_ASSERT(2530, params->proc != NULL); + IRO_ASSERT(2531, params->ptfCopy != NULL); + IRO_ASSERT(2532, params->mapCopy != NULL); if ((loc = PointsToEntry_loc(tgtPTE)) && (locs = PointsToEntry_locs(tgtPTE))) { if ((block = LocationSet_block(loc))) { @@ -1313,8 +1277,7 @@ static void MatchPTFAction1(PointsToEntry *tgtPTE, void *refcon) { if (kind == PAMEMORYBLOCKKIND_LOCALVAR) { MatchPTFHelper(loc, locs, params->proc, params->mapCopy, params->ptfCopy); } else if (kind != PAMEMORYBLOCKKIND_EXTENDEDPARAM) { -#line 2547 - CError_FATAL(); + CError_FATAL(2547); } } } @@ -1327,16 +1290,14 @@ static void MatchPTFAction2(PointsToEntry *tgtPTE, void *refcon) { PAMemoryBlock *block; PAMemoryBlockKind kind; -#line 2561 - IRO_ASSERT(tgtPTE != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(2561, tgtPTE != NULL); + IRO_ASSERT(2562, refcon != NULL); params = refcon; -#line 2566 - IRO_ASSERT(params->proc != NULL); - IRO_ASSERT(params->ptfCopy != NULL); - IRO_ASSERT(params->mapCopy != NULL); + IRO_ASSERT(2566, params->proc != NULL); + IRO_ASSERT(2567, params->ptfCopy != NULL); + IRO_ASSERT(2568, params->mapCopy != NULL); if ((loc = PointsToEntry_loc(tgtPTE)) && (locs = PointsToEntry_locs(tgtPTE))) { if ((block = LocationSet_block(loc))) { @@ -1355,12 +1316,11 @@ static Boolean MatchPTF(PartialTransferFunction *tgtPTF, Object *proc, ParamMapp PointsToFunction *initial; MatchPTFActionParams params; -#line 2593 - IRO_ASSERT(tgtPTF != NULL); - IRO_ASSERT(proc != NULL); - IRO_ASSERT(map != NULL); - IRO_ASSERT(nd != NULL); - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(2593, tgtPTF != NULL); + IRO_ASSERT(2594, proc != NULL); + IRO_ASSERT(2595, map != NULL); + IRO_ASSERT(2596, nd != NULL); + IRO_ASSERT(2597, ptf != NULL); ptfCopy = PartialTransferFunction_New(); PartialTransferFunction_Copy(ptfCopy, ptf); @@ -1401,9 +1361,8 @@ static Boolean MatchPTF(PartialTransferFunction *tgtPTF, Object *proc, ParamMapp static void FindCallTargetsAction2(Object *obj, void *refcon) { ObjectSet *procList; -#line 2650 - IRO_ASSERT(obj != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(2650, obj != NULL); + IRO_ASSERT(2651, refcon != NULL); procList = refcon; @@ -1414,9 +1373,8 @@ static void FindCallTargetsAction2(Object *obj, void *refcon) { static void FindCallTargetsAction(LocationSet *ls, void *refcon) { ObjectSet *procList; -#line 2669 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(2669, ls != NULL); + IRO_ASSERT(2670, refcon != NULL); procList = refcon; @@ -1437,13 +1395,12 @@ static int FindCallTargets(ObjectSet *procList, Object *proc, IROLinear *nd, Par int evalResult; int result; -#line 2696 - IRO_ASSERT(procList != NULL); - IRO_ASSERT(proc != NULL); - IRO_ASSERT(nd != NULL); - IRO_ASSERT(nd->type == IROLinearFunccall); - IRO_ASSERT(map != NULL); - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(2696, procList != NULL); + IRO_ASSERT(2697, proc != NULL); + IRO_ASSERT(2698, nd != NULL); + IRO_ASSERT(2699, nd->type == IROLinearFunccall); + IRO_ASSERT(2700, map != NULL); + IRO_ASSERT(2701, ptf != NULL); set = LocationSetSet_New(); LocationSetSet_Init(set); @@ -1460,14 +1417,13 @@ static int LookupParam(LocationSetSet *set, LocationSet *ls, Object *var, Stack Boolean result; ExtendedParam *ep; -#line 2728 - IRO_ASSERT(set == NULL || set != NULL); - IRO_ASSERT(ls != NULL); - IRO_ASSERT(var != NULL); - IRO_ASSERT(stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL); - IRO_ASSERT(proc != NULL); - IRO_ASSERT(map == NULL || map != NULL); - IRO_ASSERT(ptf == NULL || ptf != NULL); + IRO_ASSERT(2728, set == NULL || set != NULL); + IRO_ASSERT(2729, ls != NULL); + IRO_ASSERT(2730, var != NULL); + IRO_ASSERT(2731, stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL); + IRO_ASSERT(2732, proc != NULL); + IRO_ASSERT(2733, map == NULL || map != NULL); + IRO_ASSERT(2734, ptf == NULL || ptf != NULL); result = 0; @@ -1475,8 +1431,7 @@ static int LookupParam(LocationSetSet *set, LocationSet *ls, Object *var, Stack if (!ep) ep = CreateExtendedParam(stackPtr, map, var, &result); -#line 2741 - IRO_ASSERT(ep != NULL); + IRO_ASSERT(2741, ep != NULL); if (ep) { PAMemoryBlock *block; @@ -1547,13 +1502,12 @@ static Boolean GetActualLocsOfExtendedParam(LocationSetSet *set, LocationSet *ls UInt32 savedStride; LocationSetSet *newSet; -#line 2821 - IRO_ASSERT(set == NULL || set != NULL); - IRO_ASSERT((ls != NULL && var == NULL) || (ls == NULL && var != NULL)); - IRO_ASSERT(ls == NULL || !LocationSet_IsUnknown(ls)); - IRO_ASSERT(var != &stUnknown); - IRO_ASSERT(stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL); - IRO_ASSERT(map == NULL || map != NULL); + IRO_ASSERT(2821, set == NULL || set != NULL); + IRO_ASSERT(2822, (ls != NULL && var == NULL) || (ls == NULL && var != NULL)); + IRO_ASSERT(2823, ls == NULL || !LocationSet_IsUnknown(ls)); + IRO_ASSERT(2824, var != &stUnknown); + IRO_ASSERT(2825, stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL); + IRO_ASSERT(2826, map == NULL || map != NULL); result = 0; block = NULL; @@ -1563,21 +1517,18 @@ static Boolean GetActualLocsOfExtendedParam(LocationSetSet *set, LocationSet *ls if (ls) { block = LocationSet_block(ls); -#line 2838 - IRO_ASSERT(block != NULL); - IRO_ASSERT(PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_EXTENDEDPARAM); + IRO_ASSERT(2838, block != NULL); + IRO_ASSERT(2839, PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_EXTENDEDPARAM); ep = PAMemoryBlock_thing(block); -#line 2842 - IRO_ASSERT(ep != NULL); + IRO_ASSERT(2842, ep != NULL); savedField = LocationSet_field(ls); savedStride = LocationSet_stride(ls); savedRtype = LocationSet_rtype(ls); } -#line 2848 - IRO_ASSERT(ep == NULL || ep != NULL); + IRO_ASSERT(2848, ep == NULL || ep != NULL); if (stackPtr && *stackPtr) { StackElement *element = Stack_Top(stackPtr); @@ -1585,12 +1536,10 @@ static Boolean GetActualLocsOfExtendedParam(LocationSetSet *set, LocationSet *ls map = StackElement_map(element); } -#line 2859 - IRO_ASSERT(map == NULL || map != NULL); + IRO_ASSERT(2859, map == NULL || map != NULL); if (ep) { -#line 2863 - IRO_ASSERT(var == NULL); + IRO_ASSERT(2863, var == NULL); ObjectSet_ForEach(ExtendedParam_objectSet(ep), FindGlobalObjectAction, &var); if (!var) var = ObjectSet_FindFirst(ExtendedParam_objectSet(ep)); @@ -1598,8 +1547,7 @@ static Boolean GetActualLocsOfExtendedParam(LocationSetSet *set, LocationSet *ls var = &stUnknown; } -#line 2870 - IRO_ASSERT(var != NULL); + IRO_ASSERT(2870, var != NULL); if (map && var != &stUnknown) { if (flag) @@ -1610,17 +1558,15 @@ static Boolean GetActualLocsOfExtendedParam(LocationSetSet *set, LocationSet *ls newSet = LocationSetSet_New(); LocationSetSet_Init(newSet); -#line 2884 - IRO_ASSERT(mapping == NULL || mapping != NULL); + IRO_ASSERT(2884, mapping == NULL || mapping != NULL); if (mapping) nd = ParamMapping_actual(mapping); if (!nd) { if (!ls) { -#line 2893 - IRO_ASSERT(var != NULL); - IRO_ASSERT(ep == NULL); + IRO_ASSERT(2893, var != NULL); + IRO_ASSERT(2894, ep == NULL); if (var != &stUnknown) { ep = CreateExtendedParam(stackPtr, NULL, var, &result); @@ -1643,8 +1589,7 @@ static Boolean GetActualLocsOfExtendedParam(LocationSetSet *set, LocationSet *ls savedRtype = NULL; } -#line 2925 - IRO_ASSERT(block != NULL); + IRO_ASSERT(2925, block != NULL); if (block == LocationSet_block(stUnknownLs)) { LocationSetSet_AddUnknown(newSet, savedRtype, NULL, NULL); @@ -1718,17 +1663,15 @@ typedef struct ExpandLocationSetSetActionParams { static void ExpandLocationSetSetToActualsAction(LocationSet *ls, void *refcon) { ExpandLocationSetSetActionParams *params; -#line 3021 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(3021, ls != NULL); + IRO_ASSERT(3022, refcon != NULL); params = refcon; -#line 3026 - IRO_ASSERT(params->toBeRemoved != NULL); - IRO_ASSERT(params->toBeAdded != NULL); - IRO_ASSERT(params->stackPtr == NULL || *params->stackPtr == NULL || *params->stackPtr != NULL); - IRO_ASSERT(params->map == NULL || params->map != NULL); + IRO_ASSERT(3026, params->toBeRemoved != NULL); + IRO_ASSERT(3027, params->toBeAdded != NULL); + IRO_ASSERT(3028, params->stackPtr == NULL || *params->stackPtr == NULL || *params->stackPtr != NULL); + IRO_ASSERT(3029, params->map == NULL || params->map != NULL); if (!LocationSet_IsUnknown(ls)) { PAMemoryBlock *block = LocationSet_block(ls); @@ -1753,10 +1696,9 @@ static int ExpandLocationSetSetToActuals(Stack **stackPtr, ParamMappingFunction ExpandLocationSetSetActionParams params; Boolean result; -#line 3063 - IRO_ASSERT(stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL); - IRO_ASSERT(map == NULL || map != NULL); - IRO_ASSERT(thingsPointedTo != NULL); + IRO_ASSERT(3063, stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL); + IRO_ASSERT(3064, map == NULL || map != NULL); + IRO_ASSERT(3065, thingsPointedTo != NULL); toBeRemoved = LocationSetSet_New(); LocationSetSet_Init(toBeRemoved); @@ -1791,15 +1733,13 @@ static void EvaluatePartialAbsolute(LocationSetSet *set, LocationSetSet *thingsP Type *absLocRtype; PAMemoryBlock *block; -#line 3108 - IRO_ASSERT(set != NULL); - IRO_ASSERT(thingsPointedTo != NULL); - IRO_ASSERT(dst != NULL); - IRO_ASSERT(indRtype != NULL); + IRO_ASSERT(3108, set != NULL); + IRO_ASSERT(3109, thingsPointedTo != NULL); + IRO_ASSERT(3110, dst != NULL); + IRO_ASSERT(3111, indRtype != NULL); absLoc = LocationSetSet_FindFirst(thingsPointedTo); -#line 3114 - IRO_ASSERT(absLoc != NULL); + IRO_ASSERT(3114, absLoc != NULL); if (!LocationSet_IsUnknown(absLoc)) absLocRtype = LocationSet_rtype(absLoc); @@ -1862,10 +1802,9 @@ static Boolean AddToInitialPointsToFunc(Boolean flag, PartialTransferFunction *p PointsToFunction *initial; PointsToEntry *pte; -#line 3192 - IRO_ASSERT(ptf == NULL || ptf != NULL); - IRO_ASSERT(dst != NULL); - IRO_ASSERT(set != NULL); + IRO_ASSERT(3192, ptf == NULL || ptf != NULL); + IRO_ASSERT(3193, dst != NULL); + IRO_ASSERT(3194, set != NULL); result = 0; @@ -1874,8 +1813,7 @@ static Boolean AddToInitialPointsToFunc(Boolean flag, PartialTransferFunction *p if (!ls || LocationSet_rtype(ls)) { initial = PartialTransferFunction_initialPointsToFn(ptf); if (initial && !PointsToFunction_FindByLookupCompatibleLocationSet(initial, dst)) { -#line 3208 - IRO_ASSERT(dst != NULL); + IRO_ASSERT(3208, dst != NULL); pte = PointsToEntry_New(); PointsToEntry_Init(pte, dst, set); @@ -1899,15 +1837,14 @@ static Boolean Lookup(LocationSetSet *set, Stack **stackPtr, Object *proc, Param ObjectSet *objSet; Object *obj; -#line 3245 - IRO_ASSERT(set == NULL || set != NULL); - IRO_ASSERT(stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL); - IRO_ASSERT(proc == NULL || proc != NULL); - IRO_ASSERT(map == NULL || map != NULL); - IRO_ASSERT(ptf == NULL || ptf != NULL); - IRO_ASSERT(dst != NULL); - IRO_ASSERT(pointsToFunc == NULL || pointsToFunc != NULL); - IRO_ASSERT(indRtype == NULL || indRtype != NULL); + IRO_ASSERT(3245, set == NULL || set != NULL); + IRO_ASSERT(3246, stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL); + IRO_ASSERT(3247, proc == NULL || proc != NULL); + IRO_ASSERT(3248, map == NULL || map != NULL); + IRO_ASSERT(3249, ptf == NULL || ptf != NULL); + IRO_ASSERT(3250, dst != NULL); + IRO_ASSERT(3251, pointsToFunc == NULL || pointsToFunc != NULL); + IRO_ASSERT(3252, indRtype == NULL || indRtype != NULL); result = 0; @@ -2028,9 +1965,8 @@ static Boolean Lookup(LocationSetSet *set, Stack **stackPtr, Object *proc, Param } static Boolean InputsHaveNewPointerValues(PartialTransferFunction *tgtPTF, PartialTransferFunction *ptf) { -#line 3393 - IRO_ASSERT(tgtPTF != NULL); - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(3393, tgtPTF != NULL); + IRO_ASSERT(3394, ptf != NULL); return 0; } @@ -2055,14 +1991,13 @@ static void CreateExtendedParamAction(ParamMapping *mapping, void *refcon) { ExtendedParam *lastEP; uint32 lastValue; -#line 3417 - IRO_ASSERT(mapping != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(3417, mapping != NULL); + IRO_ASSERT(3418, refcon != NULL); params = refcon; - IRO_ASSERT(params->last == NULL || params->last != NULL); - IRO_ASSERT(params->lowest == NULL || params->lowest != NULL); + IRO_ASSERT(3422, params->last == NULL || params->last != NULL); + IRO_ASSERT(3423, params->lowest == NULL || params->lowest != NULL); if ((ep = ParamMapping_extended(mapping))) { value = ExtendedParam_sub_489110(ep); @@ -2093,11 +2028,10 @@ static ExtendedParam *FindMatchingExtendedParam(Stack **stackPtr, ParamMappingFu ExtendedParam *ep; ExtendedParam *lowestEP; -#line 3473 - IRO_ASSERT(stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL); - IRO_ASSERT(map == NULL || map != NULL); - IRO_ASSERT(lss != NULL); - IRO_ASSERT(lowest != NULL); + IRO_ASSERT(3473, stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL); + IRO_ASSERT(3474, map == NULL || map != NULL); + IRO_ASSERT(3475, lss != NULL); + IRO_ASSERT(3476, lowest != NULL); ep = NULL; if ((lowestEP = ParamMapping_extended(lowest))) { @@ -2134,10 +2068,9 @@ static ExtendedParam *CreateExtendedParam(Stack **stackPtr, ParamMappingFunction LocationSetSet *lss; CreateEPActionParams params; -#line 3518 - IRO_ASSERT(map == NULL || map != NULL); - IRO_ASSERT(stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL); - IRO_ASSERT(var != NULL); + IRO_ASSERT(3518, map == NULL || map != NULL); + IRO_ASSERT(3519, stackPtr == NULL || *stackPtr == NULL || *stackPtr != NULL); + IRO_ASSERT(3520, var != NULL); mapping = NULL; if (map) @@ -2145,10 +2078,8 @@ static ExtendedParam *CreateExtendedParam(Stack **stackPtr, ParamMappingFunction ep = ExtendedParam_FindByObject(var); if (ep) { - if (mapping) { -#line 3535 - IRO_ASSERT(ep == ParamMapping_extended(mapping) || ParamMapping_extended(mapping) == NULL); - } + if (mapping) + IRO_ASSERT(3535, ep == ParamMapping_extended(mapping) || ParamMapping_extended(mapping) == NULL); } else if (map && !ObjectIsRestrictQualified(var)) { lss = LocationSetSet_New(); LocationSetSet_Init(lss); @@ -2181,26 +2112,23 @@ static ExtendedParam *CreateExtendedParam(Stack **stackPtr, ParamMappingFunction if (stExtParamSet) ExtParamSet_sub_487630(stExtParamSet, ep); -#line 3583 - IRO_ASSERT(ep != NULL); + IRO_ASSERT(3583, ep != NULL); return ep; } #ifdef IRO_DEBUG void __assertion_failed(char *expr, char *filename, int line) { -#line 3605 - CError_ASSERT(filename); + CError_ASSERT(3605, filename); CError_Internal(filename, line); } #endif static void RecordActuals(IROLinear *nd, Object *proc, ParamMappingFunction *map) { -#line 3628 - IRO_ASSERT(nd != NULL); - IRO_ASSERT(nd->type == IROLinearFunccall); - IRO_ASSERT(proc != NULL); - IRO_ASSERT(map != NULL); + IRO_ASSERT(3628, nd != NULL); + IRO_ASSERT(3629, nd->type == IROLinearFunccall); + IRO_ASSERT(3630, proc != NULL); + IRO_ASSERT(3631, map != NULL); if (proc != &stUnknown) { int i; @@ -2214,8 +2142,7 @@ static void RecordActuals(IROLinear *nd, Object *proc, ParamMappingFunction *map arg = &stUnknown; for (i = 0; i < nd->u.funccall.argCount; i++) { -#line 3643 - IRO_ASSERT(arg != NULL); + IRO_ASSERT(3643, arg != NULL); if (arg != &stUnknown) { ParamMapping *mapping = ParamMapping_New(); @@ -2237,10 +2164,9 @@ static void RecordActuals(IROLinear *nd, Object *proc, ParamMappingFunction *map } static Boolean IsAddressableLocation(LocationSet *loc, Object *proc, IRONode *fnode, IROLinear *nd) { -#line 3676 - IRO_ASSERT(loc != NULL); - IRO_ASSERT(fnode != NULL); - IRO_ASSERT(nd != NULL); + IRO_ASSERT(3676, loc != NULL); + IRO_ASSERT(3677, fnode != NULL); + IRO_ASSERT(3678, nd != NULL); if (!LocationSet_IsUnknown(loc)) { PAMemoryBlock *block; @@ -2277,9 +2203,8 @@ static Boolean IsAddressableLocation(LocationSet *loc, Object *proc, IRONode *fn } static Boolean LocationSetsAlias(LocationSet *ls1, LocationSet *ls2) { -#line 3719 - IRO_ASSERT(ls1 != NULL); - IRO_ASSERT(ls2 != NULL); + IRO_ASSERT(3719, ls1 != NULL); + IRO_ASSERT(3720, ls2 != NULL); return (ls1 == ls2) || @@ -2319,9 +2244,8 @@ static void FindAliasingAction2(LocationSet *ls, void *refcon) { static void FindAliasingAction(LocationSet *ls, void *refcon) { FindAliasingParams *params; -#line 3751 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(3751, ls != NULL); + IRO_ASSERT(3752, refcon != NULL); params = refcon; @@ -2351,24 +2275,21 @@ static void KillAllAddressableLocationsAction(PointsToEntry *pte, void *refcon) KillLocationParams *params; LocationSet *loc; -#line 3779 - IRO_ASSERT(pte != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(3779, pte != NULL); + IRO_ASSERT(3780, refcon != NULL); params = refcon; -#line 3784 - IRO_ASSERT(params->proc != NULL); - IRO_ASSERT(params->fnode != NULL); - IRO_ASSERT(params->nd != NULL); - IRO_ASSERT(params->ptf != NULL); - IRO_ASSERT(params->toBeKilled != NULL); - IRO_ASSERT(params->dst == NULL); + IRO_ASSERT(3784, params->proc != NULL); + IRO_ASSERT(3785, params->fnode != NULL); + IRO_ASSERT(3786, params->nd != NULL); + IRO_ASSERT(3787, params->ptf != NULL); + IRO_ASSERT(3788, params->toBeKilled != NULL); + IRO_ASSERT(3789, params->dst == NULL); loc = PointsToEntry_loc(pte); -#line 3793 - IRO_ASSERT(loc != NULL); - IRO_ASSERT(!LocationSet_IsUnknown(loc)); + IRO_ASSERT(3793, loc != NULL); + IRO_ASSERT(3794, !LocationSet_IsUnknown(loc)); if (IsAddressableLocation(loc, params->proc, params->fnode, params->nd)) PointsToFunction_Add(params->toBeKilled, pte); @@ -2378,26 +2299,23 @@ static void KillAllAliasingExtParamLocsAction(PointsToEntry *pte, void *refcon) KillLocationParams *params; LocationSet *loc; -#line 3813 - IRO_ASSERT(pte != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(3813, pte != NULL); + IRO_ASSERT(3814, refcon != NULL); params = refcon; -#line 3818 - IRO_ASSERT(params->proc != NULL); - IRO_ASSERT(params->fnode != NULL); - IRO_ASSERT(params->nd != NULL); - IRO_ASSERT(params->ptf != NULL); - IRO_ASSERT(params->toBeKilled != NULL); - IRO_ASSERT(params->dst != NULL); - IRO_ASSERT(LocationSet_block(params->dst) != NULL); - IRO_ASSERT(PAMemoryBlock_kind(LocationSet_block(params->dst)) == PAMEMORYBLOCKKIND_EXTENDEDPARAM); + IRO_ASSERT(3818, params->proc != NULL); + IRO_ASSERT(3819, params->fnode != NULL); + IRO_ASSERT(3820, params->nd != NULL); + IRO_ASSERT(3821, params->ptf != NULL); + IRO_ASSERT(3822, params->toBeKilled != NULL); + IRO_ASSERT(3823, params->dst != NULL); + IRO_ASSERT(3824, LocationSet_block(params->dst) != NULL); + IRO_ASSERT(3825, PAMemoryBlock_kind(LocationSet_block(params->dst)) == PAMEMORYBLOCKKIND_EXTENDEDPARAM); loc = PointsToEntry_loc(pte); -#line 3829 - IRO_ASSERT(loc != NULL); - IRO_ASSERT(!LocationSet_IsUnknown(loc)); + IRO_ASSERT(3829, loc != NULL); + IRO_ASSERT(3830, !LocationSet_IsUnknown(loc)); if (loc != params->dst) { if (LocationSetsAlias(loc, params->dst)) { @@ -2452,24 +2370,21 @@ static void KillLocationsAction(PointsToEntry *pte, void *refcon) { LocationSet *loc; LocationSetSet *lss; -#line 3886 - IRO_ASSERT(pte != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(3886, pte != NULL); + IRO_ASSERT(3887, refcon != NULL); params = refcon; -#line 3891 - IRO_ASSERT(params->proc != NULL); - IRO_ASSERT(params->fnode != NULL); - IRO_ASSERT(params->nd != NULL); - IRO_ASSERT(params->ptf != NULL); - IRO_ASSERT(params->toBeKilled != NULL); - IRO_ASSERT(params->dst == NULL); + IRO_ASSERT(3891, params->proc != NULL); + IRO_ASSERT(3892, params->fnode != NULL); + IRO_ASSERT(3893, params->nd != NULL); + IRO_ASSERT(3894, params->ptf != NULL); + IRO_ASSERT(3895, params->toBeKilled != NULL); + IRO_ASSERT(3896, params->dst == NULL); loc = PointsToEntry_loc(pte); -#line 3900 - IRO_ASSERT(loc != NULL); - IRO_ASSERT(!LocationSet_IsUnknown(loc)); + IRO_ASSERT(3900, loc != NULL); + IRO_ASSERT(3901, !LocationSet_IsUnknown(loc)); lss = LocationSetSet_New(); LocationSetSet_Init(lss); @@ -2488,11 +2403,10 @@ static Boolean KillAllAddressableLocations(Object *proc, IRONode *fnode, IROLine PointsToFunction *toBeKilled; KillLocationParams params; -#line 3921 - IRO_ASSERT(proc != NULL); - IRO_ASSERT(fnode == NULL || fnode != NULL); - IRO_ASSERT(nd == NULL || nd != NULL); - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(3921, proc != NULL); + IRO_ASSERT(3922, fnode == NULL || fnode != NULL); + IRO_ASSERT(3923, nd == NULL || nd != NULL); + IRO_ASSERT(3924, ptf != NULL); if (nd && nd->pointsToFunction) pointsToFunc = nd->pointsToFunction; @@ -2538,12 +2452,11 @@ static void KillAllAliasingExtParamLocs(Object *proc, IRONode *fnode, IROLinear PointsToFunction *toBeKilled; KillLocationParams params; -#line 3974 - IRO_ASSERT(proc != NULL); - IRO_ASSERT(fnode == NULL || fnode != NULL); - IRO_ASSERT(nd == NULL || nd != NULL); - IRO_ASSERT(ptf != NULL); - IRO_ASSERT(dst != NULL); + IRO_ASSERT(3974, proc != NULL); + IRO_ASSERT(3975, fnode == NULL || fnode != NULL); + IRO_ASSERT(3976, nd == NULL || nd != NULL); + IRO_ASSERT(3977, ptf != NULL); + IRO_ASSERT(3978, dst != NULL); if (!LocationSet_IsUnknown(dst) && LocationSet_block(dst)) { if (PAMemoryBlock_kind(LocationSet_block(dst)) == PAMEMORYBLOCKKIND_EXTENDEDPARAM) { @@ -2585,13 +2498,12 @@ static Boolean Assign(PartialTransferFunction *ptf, LocationSet *dst, LocationSe LocationSet *bitfieldOf; LocationSetSet *lss; -#line 4027 - IRO_ASSERT(ptf != NULL); - IRO_ASSERT(dst != NULL); - IRO_ASSERT(srcs != NULL); - IRO_ASSERT(proc != NULL); - IRO_ASSERT(nd == NULL || nd != NULL); - IRO_ASSERT(fnode == NULL || fnode != NULL); + IRO_ASSERT(4027, ptf != NULL); + IRO_ASSERT(4028, dst != NULL); + IRO_ASSERT(4029, srcs != NULL); + IRO_ASSERT(4030, proc != NULL); + IRO_ASSERT(4031, nd == NULL || nd != NULL); + IRO_ASSERT(4032, fnode == NULL || fnode != NULL); if (nd) { if (!nd->pointsToFunction) { @@ -2607,9 +2519,8 @@ static Boolean Assign(PartialTransferFunction *ptf, LocationSet *dst, LocationSe if (pte) { loc = PointsToEntry_loc(pte); locs = PointsToEntry_locs(pte); -#line 4056 - IRO_ASSERT(!LocationSet_IsUnknown(dst)); - IRO_ASSERT(LocationSet_stride(dst) == 0 || LocationSet_stride(loc) != 0); + IRO_ASSERT(4056, !LocationSet_IsUnknown(dst)); + IRO_ASSERT(4057, LocationSet_stride(dst) == 0 || LocationSet_stride(loc) != 0); result = !LocationSetSets_Equal(srcs, locs) || LocationSet_stride(dst) != LocationSet_stride(loc); @@ -2665,18 +2576,16 @@ static void EvalMeetAction(PointsToEntry *pte, void *refcon) { LocationSetSet *set; UInt16 i; -#line 4123 - IRO_ASSERT(pte != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(4123, pte != NULL); + IRO_ASSERT(4124, refcon != NULL); params = refcon; -#line 4128 - IRO_ASSERT(params->proc != NULL); - IRO_ASSERT(params->fnode != NULL); - IRO_ASSERT(params->pred != NULL); - IRO_ASSERT(params->nd != NULL); - IRO_ASSERT(params->ptf != NULL); + IRO_ASSERT(4128, params->proc != NULL); + IRO_ASSERT(4129, params->fnode != NULL); + IRO_ASSERT(4130, params->pred != NULL); + IRO_ASSERT(4131, params->nd != NULL); + IRO_ASSERT(4132, params->ptf != NULL); loc = PointsToEntry_loc(pte); @@ -2701,11 +2610,10 @@ static Boolean EvalMeet(Object *proc, IRONode *fnode, IROLinear *nd, PartialTran EvalMeetActionParams params; int i; -#line 4163 - IRO_ASSERT(proc != NULL); - IRO_ASSERT(fnode != NULL); - IRO_ASSERT(nd != NULL); - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(4163, proc != NULL); + IRO_ASSERT(4164, fnode != NULL); + IRO_ASSERT(4165, nd != NULL); + IRO_ASSERT(4166, ptf != NULL); pointsToFunc = PointsToFunction_New(); if (nd->pointsToFunction) @@ -2745,11 +2653,10 @@ static Boolean EvalMeet(Object *proc, IRONode *fnode, IROLinear *nd, PartialTran static PartialTransferFunction *AllocatePTF(Object *proc, IROLinear *nd, PartialTransferFunction *ptf) { PartialTransferFunction *newPTF; -#line 4210 - IRO_ASSERT(proc != NULL); - IRO_ASSERT(proc->u.func.ptfList != NULL); - IRO_ASSERT(nd == NULL || nd != NULL); - IRO_ASSERT(ptf == NULL || ptf != NULL); + IRO_ASSERT(4210, proc != NULL); + IRO_ASSERT(4211, proc->u.func.ptfList != NULL); + IRO_ASSERT(4212, nd == NULL || nd != NULL); + IRO_ASSERT(4213, ptf == NULL || ptf != NULL); newPTF = PartialTransferFunction_New(); PartialTransferFunction_Init(newPTF, nd, ptf); @@ -2758,8 +2665,7 @@ static PartialTransferFunction *AllocatePTF(Object *proc, IROLinear *nd, Partial } static Object *FindMainEntryPoint(Object *function) { -#line 4229 - IRO_ASSERT(function != NULL); + IRO_ASSERT(4229, function != NULL); return function; } @@ -2776,8 +2682,7 @@ static ObjectList *FunctionArguments(Object *proc) { FuncArg *args; Boolean notFound; -#line 4252 - IRO_ASSERT(proc != NULL); + IRO_ASSERT(4252, proc != NULL); if (proc == stCurrentProc) { for (list = arguments; list; list = list->next) { @@ -2866,21 +2771,17 @@ static ObjectList *FunctionArguments(Object *proc) { } static IRONode **FunctionNodeTable(Object *proc) { -#line 4383 - IRO_ASSERT(proc != NULL); + IRO_ASSERT(4383, proc != NULL); -#line 4391 - IRO_ASSERT(proc == stCurrentProc); + IRO_ASSERT(4391, proc == stCurrentProc); return IRO_NodeTable; } static IRONode *FunctionFirstNode(Object *proc) { -#line 4401 - IRO_ASSERT(proc != NULL); + IRO_ASSERT(4401, proc != NULL); -#line 4409 - IRO_ASSERT(proc == stCurrentProc); + IRO_ASSERT(4409, proc == stCurrentProc); return IRO_FirstNode; } @@ -2914,18 +2815,16 @@ static void EvalCallAction(Object *proc, void *refcon) { Boolean flag; Boolean flag2; -#line 4458 - IRO_ASSERT(proc != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(4458, proc != NULL); + IRO_ASSERT(4459, refcon != NULL); params = refcon; -#line 4463 - IRO_ASSERT(params->proc != NULL); - IRO_ASSERT(params->fnode != NULL); - IRO_ASSERT(params->nd != NULL); - IRO_ASSERT(params->ptf != NULL); - IRO_ASSERT(params->map == NULL || params->map != NULL); + IRO_ASSERT(4463, params->proc != NULL); + IRO_ASSERT(4464, params->fnode != NULL); + IRO_ASSERT(4465, params->nd != NULL); + IRO_ASSERT(4466, params->ptf != NULL); + IRO_ASSERT(4467, params->map == NULL || params->map != NULL); if (!params->x18) { pmf = ParamMappingFunction_New(); @@ -2945,8 +2844,7 @@ static void EvalCallAction(Object *proc, void *refcon) { StackElement_Term(element); StackElement_Delete(element); -#line 4490 - IRO_ASSERT(tgtPTF != NULL); + IRO_ASSERT(4490, tgtPTF != NULL); flag = 1; @@ -2984,12 +2882,11 @@ static Boolean EvalCall(Object *proc, IRONode *fnode, IROLinear *nd, ParamMappin EvalCallActionParams params; ObjectSet *objSet; -#line 4548 - IRO_ASSERT(proc != NULL); - IRO_ASSERT(fnode != NULL); - IRO_ASSERT(nd != NULL); - IRO_ASSERT(map != NULL); - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(4548, proc != NULL); + IRO_ASSERT(4549, fnode != NULL); + IRO_ASSERT(4550, nd != NULL); + IRO_ASSERT(4551, map != NULL); + IRO_ASSERT(4552, ptf != NULL); memset(¶ms, 0, sizeof(params)); params.proc = proc; @@ -3031,8 +2928,7 @@ static void AdjustTypesForVolatilityAction(LocationSet *ls, void *refcon) { qual = TYPE_MEMBER_POINTER(type)->qual; break; default: -#line 4604 - CError_FATAL(); + CError_FATAL(4604); } if (!(qual & Q_VOLATILE)) { @@ -3082,17 +2978,15 @@ static void EvalAssignAction2(LocationSet *ls, void *refcon) { Type *rtype; PAMemoryBlock *block; -#line 4657 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(4657, ls != NULL); + IRO_ASSERT(4658, refcon != NULL); params = refcon; if (!params->xC && !LocationSet_IsUnknown(ls)) { value = params->x0; nd = params->nd; -#line 4665 - IRO_ASSERT(nd != NULL); + IRO_ASSERT(4665, nd != NULL); oper = nd->nodetype; stride = LocationSet_stride(ls); @@ -3170,8 +3064,7 @@ static void EvalAssignAction2(LocationSet *ls, void *refcon) { value = CInt64_Or(*((CInt64 *) PAMemoryBlock_thing(block)), value); break; default: -#line 4746 - CError_FATAL(); + CError_FATAL(4746); } block = PAMemoryBlock_New(); @@ -3225,18 +3118,16 @@ static void EvalAssignAction(LocationSet *dst, void *refcon) { EvalAssignActionParams *params; LocationSetSet *srcs; -#line 4797 - IRO_ASSERT(dst != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(4797, dst != NULL); + IRO_ASSERT(4798, refcon != NULL); params = refcon; -#line 4802 - IRO_ASSERT(params->proc != NULL); - IRO_ASSERT(params->ptf != NULL); - IRO_ASSERT(params->nd != NULL); - IRO_ASSERT(params->fnode != NULL); - IRO_ASSERT(params->srcs != NULL); + IRO_ASSERT(4802, params->proc != NULL); + IRO_ASSERT(4802, params->ptf != NULL); + IRO_ASSERT(4803, params->nd != NULL); + IRO_ASSERT(4804, params->fnode != NULL); + IRO_ASSERT(4805, params->srcs != NULL); srcs = params->srcs; if ( @@ -3264,12 +3155,11 @@ static Boolean EvalAssign(Object *proc, IROLinear *nd, IRONode *fnode, ParamMapp PAMemoryBlock *block; Type *type; -#line 4840 - IRO_ASSERT(proc != NULL); - IRO_ASSERT(nd != NULL); - IRO_ASSERT(fnode != NULL); - IRO_ASSERT(map != NULL); - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(4840, proc != NULL); + IRO_ASSERT(4841, nd != NULL); + IRO_ASSERT(4842, fnode != NULL); + IRO_ASSERT(4843, map != NULL); + IRO_ASSERT(4844, ptf != NULL); memset(¶ms, 0, sizeof(params)); params.proc = proc; @@ -3285,8 +3175,7 @@ static Boolean EvalAssign(Object *proc, IROLinear *nd, IRONode *fnode, ParamMapp LocationSetSet_Init(params.srcs); if (nd->type == IROLinearOp2Arg) { -#line 4861 - IRO_ASSERT(nd->u.diadic.left->type == IROLinearOp1Arg && nd->u.diadic.left->nodetype == EINDIRECT); + IRO_ASSERT(4861, nd->u.diadic.left->type == IROLinearOp1Arg && nd->u.diadic.left->nodetype == EINDIRECT); params.x15 |= EvalExpr(set, proc, nd->u.diadic.left->u.monadic, &stCallingContextStack, map, ptf); AdjustTypesForVolatility(set, proc, nd->u.diadic.left); @@ -3348,8 +3237,7 @@ static Boolean EvalAssign(Object *proc, IROLinear *nd, IRONode *fnode, ParamMapp } } } else if (nd->type == IROLinearOp1Arg) { -#line 4958 - IRO_ASSERT(nd->u.monadic.left->type == IROLinearOp1Arg && nd->u.monadic->nodetype == EINDIRECT); + IRO_ASSERT(4958, nd->u.monadic.left->type == IROLinearOp1Arg && nd->u.monadic->nodetype == EINDIRECT); params.x15 |= EvalExpr(set, proc, nd->u.monadic->u.monadic, &stCallingContextStack, map, ptf); AdjustTypesForVolatility(set, proc, nd->u.monadic); @@ -3393,8 +3281,7 @@ static Boolean EvalAssign(Object *proc, IROLinear *nd, IRONode *fnode, ParamMapp break; } } else { -#line 5006 - CError_FATAL(); + CError_FATAL(5006); } if (LocationSetSet_Count(params.srcs) != 0) { @@ -3432,13 +3319,12 @@ static Boolean EvalReturn(Object *proc, IROLinear *nd, IRONode *fnode, ParamMapp EvalAssignActionParams params; LocationSet *loc; -#line 5046 - IRO_ASSERT(proc != NULL); - IRO_ASSERT(nd != NULL); - IRO_ASSERT(nd->type == IROLinearReturn); - IRO_ASSERT(fnode != NULL); - IRO_ASSERT(map != NULL); - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(5046, proc != NULL); + IRO_ASSERT(5047, nd != NULL); + IRO_ASSERT(5048, nd->type == IROLinearReturn); + IRO_ASSERT(5049, fnode != NULL); + IRO_ASSERT(5050, map != NULL); + IRO_ASSERT(5051, ptf != NULL); memset(¶ms, 0, sizeof(params)); params.proc = proc; @@ -3496,33 +3382,29 @@ static void ApplySummaryAction2(ParamMapping *mapping, void *refcon) { LocationSetSet *set; EvalAssignActionParams assignParams; -#line 5108 - IRO_ASSERT(mapping != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(5108, mapping != NULL); + IRO_ASSERT(5109, refcon != NULL); params = refcon; -#line 5113 - IRO_ASSERT(params->tgtMap != NULL); - IRO_ASSERT(params->proc != NULL); - IRO_ASSERT(params->fnode != NULL); - IRO_ASSERT(params->nd != NULL); - IRO_ASSERT(params->nd->type == IROLinearFunccall); - IRO_ASSERT(params->ptf != NULL); - IRO_ASSERT(params->map != NULL); - IRO_ASSERT(params->loc != NULL); - IRO_ASSERT(params->locs != NULL); + IRO_ASSERT(5113, params->tgtMap != NULL); + IRO_ASSERT(5114, params->proc != NULL); + IRO_ASSERT(5115, params->fnode != NULL); + IRO_ASSERT(5116, params->nd != NULL); + IRO_ASSERT(5117, params->nd->type == IROLinearFunccall); + IRO_ASSERT(5118, params->ptf != NULL); + IRO_ASSERT(5119, params->map != NULL); + IRO_ASSERT(5120, params->loc != NULL); + IRO_ASSERT(5121, params->locs != NULL); block = LocationSet_block(params->loc); -#line 5124 - IRO_ASSERT(block != NULL); - IRO_ASSERT(PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_EXTENDEDPARAM); + IRO_ASSERT(5124, block != NULL); + IRO_ASSERT(5125, PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_EXTENDEDPARAM); ep = PAMemoryBlock_thing(block); -#line 5127 - IRO_ASSERT(ep != NULL); + IRO_ASSERT(5127, ep != NULL); if (ParamMapping_extended(mapping) == ep && (nd = ParamMapping_actual(mapping))) { set = LocationSetSet_New(); @@ -3564,26 +3446,23 @@ static void ApplySummaryAction(PointsToEntry *pte, void *refcon) { LocationSet *loc; PAMemoryBlock *block; -#line 5175 - IRO_ASSERT(pte != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(5175, pte != NULL); + IRO_ASSERT(5176, refcon != NULL); params = refcon; -#line 5180 - IRO_ASSERT(params->tgtMap != NULL); - IRO_ASSERT(params->proc != NULL); - IRO_ASSERT(params->fnode != NULL); - IRO_ASSERT(params->nd != NULL); - IRO_ASSERT(params->nd->type == IROLinearFunccall); - IRO_ASSERT(params->ptf != NULL); - IRO_ASSERT(params->map != NULL); + IRO_ASSERT(5180, params->tgtMap != NULL); + IRO_ASSERT(5181, params->proc != NULL); + IRO_ASSERT(5182, params->fnode != NULL); + IRO_ASSERT(5183, params->nd != NULL); + IRO_ASSERT(5184, params->nd->type == IROLinearFunccall); + IRO_ASSERT(5185, params->ptf != NULL); + IRO_ASSERT(5186, params->map != NULL); loc = PointsToEntry_loc(pte); -#line 5189 - IRO_ASSERT(loc != NULL); - IRO_ASSERT(!LocationSet_IsUnknown(loc)); + IRO_ASSERT(5189, loc != NULL); + IRO_ASSERT(5190, !LocationSet_IsUnknown(loc)); block = LocationSet_block(loc); if (block && PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_EXTENDEDPARAM) { @@ -3598,15 +3477,14 @@ static Boolean ApplySummary(PartialTransferFunction *tgtPTF, ParamMappingFunctio ApplySummaryActionParams params; PointsToFunction *pointsToFunc; -#line 5208 - IRO_ASSERT(tgtPTF != NULL); - IRO_ASSERT(tgtMap != NULL); - IRO_ASSERT(proc != NULL); - IRO_ASSERT(fnode != NULL); - IRO_ASSERT(nd != NULL); - IRO_ASSERT(nd->type == IROLinearFunccall); - IRO_ASSERT(ptf != NULL); - IRO_ASSERT(map != NULL); + IRO_ASSERT(5208, tgtPTF != NULL); + IRO_ASSERT(5209, tgtMap != NULL); + IRO_ASSERT(5210, proc != NULL); + IRO_ASSERT(5211, fnode != NULL); + IRO_ASSERT(5212, nd != NULL); + IRO_ASSERT(5213, nd->type == IROLinearFunccall); + IRO_ASSERT(5214, ptf != NULL); + IRO_ASSERT(5215, map != NULL); StoreReturnedLocations(nd, tgtPTF, tgtMap); if (tgtPTF == stUnknownPTF) { @@ -3646,8 +3524,7 @@ static Boolean ApplySummary(PartialTransferFunction *tgtPTF, ParamMappingFunctio } static void GetPTFAction2(ParamMapping *mapping, void *refcon) { -#line 5331 - IRO_ASSERT(mapping != NULL); + IRO_ASSERT(5331, mapping != NULL); if (ParamMapping_extended(mapping)) ParamMapping_SetExtended(mapping, NULL); @@ -3672,19 +3549,17 @@ typedef struct GetPTFActionParams { static void GetPTFAction(PartialTransferFunction *tgtPTF, void *refcon) { GetPTFActionParams *params; -#line 5359 - IRO_ASSERT(tgtPTF != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(5359, tgtPTF != NULL); + IRO_ASSERT(5360, refcon != NULL); params = refcon; -#line 5364 - IRO_ASSERT(params->map != NULL); - IRO_ASSERT(params->proc != NULL); - IRO_ASSERT(params->proc != &stUnknown); - IRO_ASSERT(params->nd != NULL); - IRO_ASSERT(params->ptf != NULL); - IRO_ASSERT(params->needVisit != NULL); + IRO_ASSERT(5364, params->map != NULL); + IRO_ASSERT(5365, params->proc != NULL); + IRO_ASSERT(5366, params->proc != &stUnknown); + IRO_ASSERT(5367, params->nd != NULL); + IRO_ASSERT(5368, params->ptf != NULL); + IRO_ASSERT(5369, params->needVisit != NULL); if (!params->x18) { if (MatchPTF(tgtPTF, params->proc, params->map, params->nd, params->ptf)) { @@ -3704,12 +3579,11 @@ static PartialTransferFunction *GetPTF(ParamMappingFunction *map, Object *proc, PartialTransferFunction *result; GetPTFActionParams params; -#line 5396 - IRO_ASSERT(map != NULL); - IRO_ASSERT(proc != NULL); - IRO_ASSERT(nd != NULL); - IRO_ASSERT(ptf != NULL); - IRO_ASSERT(needVisit != NULL); + IRO_ASSERT(5396, map != NULL); + IRO_ASSERT(5397, proc != NULL); + IRO_ASSERT(5398, nd != NULL); + IRO_ASSERT(5399, ptf != NULL); + IRO_ASSERT(5400, needVisit != NULL); if (proc == &stUnknown) { result = stUnknownPTF; @@ -3750,9 +3624,8 @@ static Boolean IsMeetNode(IRONode *fnode, IROLinear *nd) { } static Boolean IsExitNode(Object *proc, IRONode *fnode) { -#line 5467 - IRO_ASSERT(proc != NULL); - IRO_ASSERT(fnode != NULL); + IRO_ASSERT(5467, proc != NULL); + IRO_ASSERT(5468, fnode != NULL); return (fnode->numsucc == 0) && Bv_IsBitSet(FunctionFirstNode(proc)->index, fnode->dom); } @@ -3760,9 +3633,8 @@ static Boolean IsExitNode(Object *proc, IRONode *fnode) { static Boolean SomePredecessorHasBeenVisited(Object *proc, IRONode *fnode) { UInt16 i; -#line 5479 - IRO_ASSERT(proc != NULL); - IRO_ASSERT(fnode != NULL); + IRO_ASSERT(5479, proc != NULL); + IRO_ASSERT(5480, fnode != NULL); for (i = 0; i < fnode->numpred; i++) { if (FunctionNodeTable(proc)[fnode->pred[i]]->x3C) @@ -3775,8 +3647,8 @@ static Boolean SomePredecessorHasBeenVisited(Object *proc, IRONode *fnode) { static Boolean AllPredecessorsHaveBeenVisited(Object *proc, IRONode *fnode) { UInt16 i; - IRO_ASSERT(proc != NULL); - IRO_ASSERT(fnode != NULL); + IRO_ASSERT(0, proc != NULL); + IRO_ASSERT(0, fnode != NULL); for (i = 0; i < fnode->numpred; i++) { if (!FunctionNodeTable(proc)[fnode->pred[i]]->x3C) @@ -3805,22 +3677,19 @@ static void EvalProcAction2(PointsToEntry *pte, void *refcon) { LocationSetSet *set; IRONode *node; -#line 5525 - IRO_ASSERT(pte != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(5525, pte != NULL); + IRO_ASSERT(5526, refcon != NULL); params = refcon; -#line 5530 - IRO_ASSERT(params->proc != NULL); - IRO_ASSERT(params->fnode != NULL); - IRO_ASSERT(params->ptf != NULL); + IRO_ASSERT(5530, params->proc != NULL); + IRO_ASSERT(5531, params->fnode != NULL); + IRO_ASSERT(5532, params->ptf != NULL); dst = PointsToEntry_loc(pte); -#line 5535 - IRO_ASSERT(dst != NULL); - IRO_ASSERT(!LocationSet_IsUnknown(dst)); + IRO_ASSERT(5535, dst != NULL); + IRO_ASSERT(5536, !LocationSet_IsUnknown(dst)); block = LocationSet_block(dst); @@ -3862,17 +3731,15 @@ static void AssignEachInPointsToFunctionAction(PointsToEntry *pte, void *refcon) LocationSet *dst; LocationSetSet *srcs; -#line 5577 - IRO_ASSERT(pte != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(5577, pte != NULL); + IRO_ASSERT(5578, refcon != NULL); params = refcon; -#line 5582 - IRO_ASSERT(params->proc != NULL); - IRO_ASSERT(params->nd != NULL); - IRO_ASSERT(params->fnode != NULL); - IRO_ASSERT(params->ptf != NULL); + IRO_ASSERT(5582, params->proc != NULL); + IRO_ASSERT(5583, params->nd != NULL); + IRO_ASSERT(5584, params->fnode != NULL); + IRO_ASSERT(5585, params->ptf != NULL); dst = PointsToEntry_loc(pte); @@ -3888,14 +3755,12 @@ static void AssignEachInPointsToFunction(PointsToFunction *pointsTo, void *refco AssignEachInPointsToFunctionActionParams *params; PointsToFunction *pointsToFunc; -#line 5602 - IRO_ASSERT(pointsTo != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(5602, pointsTo != NULL); + IRO_ASSERT(5603, refcon != NULL); params = refcon; -#line 5607 - IRO_ASSERT(params->nd != NULL); + IRO_ASSERT(5607, params->nd != NULL); pointsToFunc = PointsToFunction_New(); if (params->nd->pointsToFunction) @@ -3929,10 +3794,9 @@ static void AssignEachInPointsToFunction(PointsToFunction *pointsTo, void *refco static Boolean ObjectIsAFunctionArgument(Object *proc, Object *obj) { ObjectList *list; -#line 5643 - IRO_ASSERT(proc != NULL); - IRO_ASSERT(proc != &stUnknown); - IRO_ASSERT(obj != NULL); + IRO_ASSERT(5643, proc != NULL); + IRO_ASSERT(5644, proc != &stUnknown); + IRO_ASSERT(5645, obj != NULL); if (obj->datatype == DLOCAL) { for (list = FunctionArguments(proc); list; list = list->next) { @@ -3947,10 +3811,9 @@ static Boolean ObjectIsAFunctionArgument(Object *proc, Object *obj) { static Boolean ObjectIsARealFunctionArgument(Object *proc, Object *obj) { ObjectList *list; -#line 5661 - IRO_ASSERT(proc != NULL); - IRO_ASSERT(proc != &stUnknown); - IRO_ASSERT(obj != NULL); + IRO_ASSERT(5661, proc != NULL); + IRO_ASSERT(5662, proc != &stUnknown); + IRO_ASSERT(5663, obj != NULL); if (obj->datatype == DLOCAL && proc == cscope_currentfunc) { for (list = arguments; list; list = list->next) { @@ -3963,10 +3826,9 @@ static Boolean ObjectIsARealFunctionArgument(Object *proc, Object *obj) { } static void AddLocalVarsAddressedByExceptionUses(Object *var) { -#line 5699 - IRO_ASSERT(var != NULL); - IRO_ASSERT(stExceptionFNode != NULL); - IRO_ASSERT(stExceptionFNode->addressed != NULL); + IRO_ASSERT(5699, var != NULL); + IRO_ASSERT(5700, stExceptionFNode != NULL); + IRO_ASSERT(5701, stExceptionFNode->addressed != NULL); if (var->datatype == DLOCAL) ObjectSet_sub_4867D0(stExceptionFNode->addressed, var); @@ -4020,9 +3882,8 @@ static void EvalProcAction(IROLinear *Int, Boolean flag) { static int userBreakCounter; if (!flag && !Int->x1E) { -#line 5748 - IRO_ASSERT(Int != NULL); - IRO_ASSERT(stEvalProcActionParams.changed != NULL); + IRO_ASSERT(5748, Int != NULL); + IRO_ASSERT(5749, stEvalProcActionParams.changed != NULL); proc = stEvalProcActionParams.proc; fnode = stEvalProcActionParams.fnode; @@ -4033,11 +3894,10 @@ static void EvalProcAction(IROLinear *Int, Boolean flag) { x18 = stEvalProcActionParams.x18; x19 = stEvalProcActionParams.x19; -#line 5760 - IRO_ASSERT(proc != NULL); - IRO_ASSERT(fnode != NULL); - IRO_ASSERT(map != NULL); - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(5760, proc != NULL); + IRO_ASSERT(5761, fnode != NULL); + IRO_ASSERT(5762, map != NULL); + IRO_ASSERT(5763, ptf != NULL); if (++userBreakCounter > 40) { IRO_CheckForUserBreak(); @@ -4145,10 +4005,9 @@ static void EvalProc(Object *proc, ParamMappingFunction *map, PartialTransferFun AssignEachInPointsToFunctionActionParams assignParams; EvalProcActionParams params; -#line 5964 - IRO_ASSERT(proc != NULL); - IRO_ASSERT(map != NULL); - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(5964, proc != NULL); + IRO_ASSERT(5965, map != NULL); + IRO_ASSERT(5966, ptf != NULL); for (fnode = FunctionFirstNode(proc); fnode; fnode = fnode->nextnode) fnode->x3C = 0; @@ -4213,10 +4072,8 @@ static void EvalProc(Object *proc, ParamMappingFunction *map, PartialTransferFun } clock(); - if (++passCount > 32) { -#line 6072 - CError_FATAL(); - } + if (++passCount > 32) + CError_FATAL(6072); } while (changed); if (passCount > stMaxPassCount) @@ -4253,9 +4110,8 @@ static void CleanseLocationSet(LocationSet *loc, void *refcon) { PAMemoryBlock *block; PALocalVar *local; -#line 6161 - IRO_ASSERT(loc != NULL); - IRO_ASSERT(refcon == NULL); + IRO_ASSERT(6161, loc != NULL); + IRO_ASSERT(6162, refcon == NULL); if ( !LocationSet_IsUnknown(loc) && @@ -4268,18 +4124,16 @@ static void CleanseLocationSet(LocationSet *loc, void *refcon) { } static void CleansePointsToEntry(PointsToEntry *pte, void *refcon) { -#line 6177 - IRO_ASSERT(pte != NULL); - IRO_ASSERT(refcon == NULL); + IRO_ASSERT(6177, pte != NULL); + IRO_ASSERT(6178, refcon == NULL); CleanseLocationSet(PointsToEntry_loc(pte), NULL); LocationSetSet_ForEach(PointsToEntry_locs(pte), CleanseLocationSet, NULL); } static void PointerAnalysis_TermAction4(PartialTransferFunction *ptf, void *refcon) { -#line 6187 - IRO_ASSERT(ptf != NULL); - IRO_ASSERT(refcon == NULL); + IRO_ASSERT(6187, ptf != NULL); + IRO_ASSERT(6188, refcon == NULL); if (ptf != stUnknownPTF) { PointsToFunction_ForEach(PartialTransferFunction_initialPointsToFn(ptf), CleansePointsToEntry, NULL); @@ -4369,8 +4223,7 @@ static void InvalidatePointsToFunctions(Object *proc) { IRONode *fnode; IROLinear *nd; -#line 6302 - IRO_ASSERT(proc != NULL); + IRO_ASSERT(6302, proc != NULL); for (fnode = FunctionFirstNode(proc); fnode; fnode = fnode->nextnode) { if (fnode->last) { @@ -4425,8 +4278,7 @@ void IRO_AnalyzePointers(Object *function) { int code; volatile heaperror_t saveheaperror; -#line 6393 - IRO_ASSERT(function != NULL); + IRO_ASSERT(6393, function != NULL); PointerAnalysis_Init(); @@ -4724,10 +4576,9 @@ static void GetDefiniteObjectOfExtendedParamLoc(LocationSet *loc, Object **resul LocationSet *tmp; PALocalVar *local; -#line 6763 - IRO_ASSERT(loc != NULL); - IRO_ASSERT(resultObj != NULL); - IRO_ASSERT(resultField != NULL); + IRO_ASSERT(6763, loc != NULL); + IRO_ASSERT(6764, resultObj != NULL); + IRO_ASSERT(6765, resultField != NULL); obj = NULL; field = LocationSet_field(loc); @@ -4735,8 +4586,7 @@ static void GetDefiniteObjectOfExtendedParamLoc(LocationSet *loc, Object **resul if (block && PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_EXTENDEDPARAM) { if ((ep = PAMemoryBlock_thing(block)) && (objSet = ExtendedParam_objectSet(ep))) { -#line 6777 - IRO_ASSERT(obj == NULL); + IRO_ASSERT(6777, obj == NULL); ObjectSet_ForEach(objSet, FindGlobalObjectAction, &obj); } } @@ -4759,8 +4609,7 @@ static void GetDefiniteObjectOfExtendedParamLoc(LocationSet *loc, Object **resul (objSet = ExtendedParam_objectSet(ep)) ) { -#line 6801 - IRO_ASSERT(obj == NULL); + IRO_ASSERT(6801, obj == NULL); ObjectSet_ForEach(objSet, FindGlobalObjectAction, &obj); } else if ( (block = LocationSet_block(tmp)) && @@ -4788,13 +4637,12 @@ static void CreateExpressionForLocationSet(LocationSet *loc, IROList *list, Type IROLinear *nd; Object *obj; -#line 6833 - IRO_ASSERT(loc != NULL); - IRO_ASSERT(!LocationSet_IsUnknown(loc)); - IRO_ASSERT(LocationSet_stride(loc) == 0); - IRO_ASSERT(list != NULL); - IRO_ASSERT(rtype != NULL); - IRO_ASSERT(proc != NULL); + IRO_ASSERT(6833, loc != NULL); + IRO_ASSERT(6834, !LocationSet_IsUnknown(loc)); + IRO_ASSERT(6835, LocationSet_stride(loc) == 0); + IRO_ASSERT(6836, list != NULL); + IRO_ASSERT(6837, rtype != NULL); + IRO_ASSERT(6838, proc != NULL); field = LocationSet_field(loc); block = LocationSet_block(loc); @@ -4834,8 +4682,7 @@ static void CreateExpressionForLocationSet(LocationSet *loc, IROList *list, Type case PAMEMORYBLOCKKIND_6: break; default: -#line 6894 - CError_FATAL(); + CError_FATAL(6894); } if (nd && !CInt64_IsZero(&field)) { @@ -4871,16 +4718,14 @@ static void LookupLinearExprAction(LocationSet *loc, void *refcon) { LookupLinearExprActionParams *params; IROListNode *list; -#line 6926 - IRO_ASSERT(loc != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(6926, loc != NULL); + IRO_ASSERT(6927, refcon != NULL); params = refcon; -#line 6931 - IRO_ASSERT(params->proc != NULL); - IRO_ASSERT(params->indirectType != NULL); - IRO_ASSERT(params->list != NULL); + IRO_ASSERT(6931, params->proc != NULL); + IRO_ASSERT(6932, params->indirectType != NULL); + IRO_ASSERT(6933, params->list != NULL); list = *params->list = IRO_malloc(sizeof(IROListNode)); IRO_InitList(&list->list); @@ -4896,8 +4741,7 @@ void PointerAnalysis_LookupLinearNodePointerExpr(Object *proc, IROLinear *indire LocationSetSet *set; LookupLinearExprActionParams params; -#line 6957 - IRO_ASSERT(indirect != NULL); + IRO_ASSERT(6957, indirect != NULL); if (indirect->pointsToFunction) { set = LocationSetSet_New(); @@ -4923,12 +4767,12 @@ static void CreateENodeForLocationSet(LocationSet *loc, ENode **resultNode, Type ENode *nd; Object *obj; - IRO_ASSERT(loc != NULL); - IRO_ASSERT(!LocationSet_IsUnknown(loc)); - IRO_ASSERT(LocationSet_stride(loc) == 0); - IRO_ASSERT(resultNode != NULL); - IRO_ASSERT(rtype != NULL); - IRO_ASSERT(proc != NULL); + IRO_ASSERT(0, loc != NULL); + IRO_ASSERT(0, !LocationSet_IsUnknown(loc)); + IRO_ASSERT(0, LocationSet_stride(loc) == 0); + IRO_ASSERT(0, resultNode != NULL); + IRO_ASSERT(0, rtype != NULL); + IRO_ASSERT(0, proc != NULL); field = LocationSet_field(loc); block = LocationSet_block(loc); @@ -4963,8 +4807,7 @@ static void CreateENodeForLocationSet(LocationSet *loc, ENode **resultNode, Type case PAMEMORYBLOCKKIND_6: break; default: -#line 7040 - CError_FATAL(); + CError_FATAL(7040); } if (nd && !CInt64_IsZero(&field)) { @@ -5002,14 +4845,14 @@ static void LookupENodeExprAction(LocationSet *loc, void *refcon) { LookupENodeExprActionParams *params; ENodeList *list; - IRO_ASSERT(loc != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(0, loc != NULL); + IRO_ASSERT(0, refcon != NULL); params = refcon; - IRO_ASSERT(params->proc != NULL); - IRO_ASSERT(params->indirectType != NULL); - IRO_ASSERT(params->list != NULL); + IRO_ASSERT(0, params->proc != NULL); + IRO_ASSERT(0, params->indirectType != NULL); + IRO_ASSERT(0, params->list != NULL); list = *params->list = IRO_malloc(sizeof(ENodeList)); list->node = NULL; @@ -5025,7 +4868,7 @@ void PointerAnalysis_LookupENodePointerExpr(Object *proc, ENode *indirect, ENode LocationSetSet *set; LookupENodeExprActionParams params; - IRO_ASSERT(indirect != NULL); + IRO_ASSERT(0, indirect != NULL); if (indirect->pointsTo) { set = LocationSetSet_New(); @@ -5043,7 +4886,7 @@ void PointerAnalysis_LookupENodePointerExpr(Object *proc, ENode *indirect, ENode } } -void PointerAnalysis_LookupVariableIntoLinearNodeExprs(Object *proc, VarRecord *var, PointsToFunction *pointsTo, IROList **list) { +void PointerAnalysis_LookupVariableIntoLinearNodeExprs(Object *proc, VarRecord *var, PointsToFunction *pointsTo, IROListNode **list) { LocationSetSet *set; LookupLinearExprActionParams params; @@ -5106,18 +4949,16 @@ static void GetFunctionDepsOrKillsAction(LocationSet *ls, void *refcon) { PALocalVar *local; Object *obj; -#line 7204 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(7204, ls != NULL); + IRO_ASSERT(7205, refcon != NULL); params = refcon; -#line 7209 - IRO_ASSERT(params->proc != NULL); - IRO_ASSERT(params->ptf != NULL); - IRO_ASSERT(params->funccall != NULL); - IRO_ASSERT(params->map == NULL || params->map != NULL); - IRO_ASSERT(params->list != NULL); + IRO_ASSERT(7209, params->proc != NULL); + IRO_ASSERT(7210, params->ptf != NULL); + IRO_ASSERT(7211, params->funccall != NULL); + IRO_ASSERT(7212, params->map == NULL || params->map != NULL); + IRO_ASSERT(7213, params->list != NULL); list = *params->list = IRO_malloc(sizeof(ObjectList)); list->object = NULL; @@ -5128,8 +4969,7 @@ static void GetFunctionDepsOrKillsAction(LocationSet *ls, void *refcon) { switch (PAMemoryBlock_kind(block)) { case PAMEMORYBLOCKKIND_EXTENDEDPARAM: if ((ep = PAMemoryBlock_thing(block)) && (objSet = ExtendedParam_objectSet(ep))) { -#line 7232 - IRO_ASSERT(obj == NULL); + IRO_ASSERT(7232, obj == NULL); ObjectSet_ForEach(objSet, FindGlobalObjectAction, &obj); } break; @@ -5154,23 +4994,20 @@ static void GetFunctionDepsOrKillsAction2(PointsToEntry *pte, void *refcon) { PAMemoryBlock *block; LocationSetSet *set; -#line 7264 - IRO_ASSERT(pte != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(7264, pte != NULL); + IRO_ASSERT(7265, refcon != NULL); params = refcon; -#line 7269 - IRO_ASSERT(params->proc != NULL); - IRO_ASSERT(params->ptf != NULL); - IRO_ASSERT(params->funccall != NULL); - IRO_ASSERT(params->map != NULL); - IRO_ASSERT(params->list != NULL); + IRO_ASSERT(7269, params->proc != NULL); + IRO_ASSERT(7270, params->ptf != NULL); + IRO_ASSERT(7271, params->funccall != NULL); + IRO_ASSERT(7272, params->map != NULL); + IRO_ASSERT(7273, params->list != NULL); loc = PointsToEntry_loc(pte); -#line 7277 - IRO_ASSERT(!LocationSet_IsUnknown(loc)); + IRO_ASSERT(7277, !LocationSet_IsUnknown(loc)); if ((block = LocationSet_block(loc)) && PAMemoryBlock_kind(block) == PAMEMORYBLOCKKIND_EXTENDEDPARAM) { set = LocationSetSet_New(); @@ -5258,10 +5095,9 @@ void PointerAnalysis_GetFunctionKills(Object *proc, IROLinear *funccall, ObjectL LocationSetSet *set; GetFunctionDepsOrKillsActionParams params; -#line 7398 - IRO_ASSERT(proc != NULL); - IRO_ASSERT(funccall != NULL); - IRO_ASSERT(funccall->type == IROLinearFunccall); + IRO_ASSERT(7398, proc != NULL); + IRO_ASSERT(7399, funccall != NULL); + IRO_ASSERT(7400, funccall->type == IROLinearFunccall); if (!ObjectIsAFunction(proc)) return; @@ -5294,10 +5130,9 @@ void PointerAnalysis_GetFunctionDependencies(Object *proc, IROLinear *funccall, PointsToFunction *finalPointsTo; GetFunctionDepsOrKillsActionParams params; -#line 7446 - IRO_ASSERT(proc != NULL); - IRO_ASSERT(funccall != NULL); - IRO_ASSERT(funccall->type == IROLinearFunccall); + IRO_ASSERT(7446, proc != NULL); + IRO_ASSERT(7447, funccall != NULL); + IRO_ASSERT(7448, funccall->type == IROLinearFunccall); if (!ObjectIsAFunction(proc)) return; @@ -5373,15 +5208,14 @@ static void ParseLocationSet(LocationSet *loc, Type *rtype, Object *proc, Create Boolean anotherFlag; Boolean isUnknown; -#line 7552 - IRO_ASSERT(loc != NULL); - IRO_ASSERT(rtype == NULL || rtype != NULL); - IRO_ASSERT(proc != NULL); - IRO_ASSERT(createNewParamObjects == CREATE_NEW_PARAM_OBJECTS_FALSE || createNewParamObjects == CREATE_NEW_PARAM_OBJECTS_TRUE); - IRO_ASSERT(resultFailed != NULL); - IRO_ASSERT(*resultFailed == false); - IRO_ASSERT(proc != NULL); - IRO_ASSERT(proc == NULL || ObjectIsAFunction(proc)); + IRO_ASSERT(7552, loc != NULL); + IRO_ASSERT(7553, rtype == NULL || rtype != NULL); + IRO_ASSERT(7554, proc != NULL); + IRO_ASSERT(7555, createNewParamObjects == CREATE_NEW_PARAM_OBJECTS_FALSE || createNewParamObjects == CREATE_NEW_PARAM_OBJECTS_TRUE); + IRO_ASSERT(7556, resultFailed != NULL); + IRO_ASSERT(7557, *resultFailed == false); + IRO_ASSERT(7558, proc != NULL); + IRO_ASSERT(7559, proc == NULL || ObjectIsAFunction(proc)); failed = 0; isUnknown = 0; @@ -5484,8 +5318,7 @@ static void ParseLocationSet(LocationSet *loc, Type *rtype, Object *proc, Create } } else { ep = obj->extParam; -#line 7687 - IRO_ASSERT(ep != NULL); + IRO_ASSERT(7687, ep != NULL); } if (!failed) { @@ -5625,15 +5458,14 @@ static void ParseLocationSet(LocationSet *loc, Type *rtype, Object *proc, Create static void ParseLocationSetSet(LocationSetSet *locs, Type *rtype, Object *proc, CreateNewParamObjects createNewParamObjects, Boolean *resultFailed) { Boolean failed; -#line 7892 - IRO_ASSERT(locs != NULL); - IRO_ASSERT(rtype == NULL || rtype != NULL); - IRO_ASSERT(proc != NULL); - IRO_ASSERT(createNewParamObjects == CREATE_NEW_PARAM_OBJECTS_FALSE || createNewParamObjects == CREATE_NEW_PARAM_OBJECTS_TRUE); - IRO_ASSERT(resultFailed != NULL); - IRO_ASSERT(*resultFailed == false); - IRO_ASSERT(proc != NULL); - IRO_ASSERT(proc == NULL || ObjectIsAFunction(proc)); + IRO_ASSERT(7892, locs != NULL); + IRO_ASSERT(7893, rtype == NULL || rtype != NULL); + IRO_ASSERT(7894, proc != NULL); + IRO_ASSERT(7895, createNewParamObjects == CREATE_NEW_PARAM_OBJECTS_FALSE || createNewParamObjects == CREATE_NEW_PARAM_OBJECTS_TRUE); + IRO_ASSERT(7896, resultFailed != NULL); + IRO_ASSERT(7897, *resultFailed == false); + IRO_ASSERT(7898, proc != NULL); + IRO_ASSERT(7899, proc == NULL || ObjectIsAFunction(proc)); failed = 0; @@ -5682,14 +5514,13 @@ static void ParseLocationSetSet(LocationSetSet *locs, Type *rtype, Object *proc, static Object *GetFunctionObjectFromDeclInfo(DeclInfo *di) { Object *proc; -#line 7953 - IRO_ASSERT(di != NULL); + IRO_ASSERT(7953, di != NULL); if (di->storageclass != TK_TYPEDEF && IS_TYPE_FUNC(di->thetype)) { Boolean flag; proc = CDecl_GetFunctionObject(di, NULL, &flag, 1); if (flag) - di->fileoffsetinfo.is_inline = 1; + di->x64 = 1; } else { proc = NULL; } @@ -5702,17 +5533,14 @@ void PointerAnalysis_ParseEntryPointsToSpecifier(DeclInfo *di) { Boolean failed; Boolean anotherFlag; -#line 7982 - IRO_ASSERT(di != NULL); + IRO_ASSERT(7982, di != NULL); proc = GetFunctionObjectFromDeclInfo(di); if (proc) { -#line 7987 - IRO_ASSERT(proc == NULL || ObjectIsAFunction(proc)); + IRO_ASSERT(7987, proc == NULL || ObjectIsAFunction(proc)); tk = lex(); -#line 7996 - IRO_ASSERT(tk == TK_IDENTIFIER && strcmp(tkidentifier->name,"entry_points_to") == 0); + IRO_ASSERT(7996, tk == TK_IDENTIFIER && strcmp(tkidentifier->name,"entry_points_to") == 0); failed = 0; @@ -5787,17 +5615,14 @@ void PointerAnalysis_ParseExitPointsToSpecifier(DeclInfo *di) { Boolean failed; Boolean anotherFlag; -#line 8097 - IRO_ASSERT(di != NULL); + IRO_ASSERT(8097, di != NULL); proc = GetFunctionObjectFromDeclInfo(di); if (proc) { -#line 8102 - IRO_ASSERT(proc == NULL || ObjectIsAFunction(proc)); + IRO_ASSERT(8102, proc == NULL || ObjectIsAFunction(proc)); tk = lex(); -#line 8111 - IRO_ASSERT(tk == TK_IDENTIFIER && strcmp(tkidentifier->name,"exit_points_to") == 0); + IRO_ASSERT(8111, tk == TK_IDENTIFIER && strcmp(tkidentifier->name,"exit_points_to") == 0); failed = 0; @@ -5877,17 +5702,14 @@ void PointerAnalysis_ParseFunctionModifiesSpecifier(DeclInfo *di) { PartialTransferFunction *ptf; LocationSetSet *ptfLSS; -#line 8211 - IRO_ASSERT(di != NULL); + IRO_ASSERT(8211, di != NULL); proc = GetFunctionObjectFromDeclInfo(di); if (proc) { -#line 8216 - IRO_ASSERT(proc == NULL || ObjectIsAFunction(proc)); + IRO_ASSERT(8216, proc == NULL || ObjectIsAFunction(proc)); tk = lex(); -#line 8225 - IRO_ASSERT(tk == TK_IDENTIFIER && strcmp(tkidentifier->name,"function_modifies") == 0); + IRO_ASSERT(8225, tk == TK_IDENTIFIER && strcmp(tkidentifier->name,"function_modifies") == 0); failed = 0; lss = LocationSetSet_New(); diff --git a/compiler_and_linker/unsorted/IroPointerAnalysisADTs.c b/compiler_and_linker/unsorted/IroPointerAnalysisADTs.c index baec435..cf54aca 100644 --- a/compiler_and_linker/unsorted/IroPointerAnalysisADTs.c +++ b/compiler_and_linker/unsorted/IroPointerAnalysisADTs.c @@ -43,17 +43,17 @@ typedef UInt32 uint32; void __assertion_failed(char *expr, char *filename, int line); #ifdef IRO_DEBUG -#define IRO_ASSERT(expr) \ +#define IRO_ASSERT(line, expr) \ do { \ if (!(expr)) { \ - __assertion_failed(#expr, __FILE__, __LINE__); \ + __assertion_failed(#expr, __FILE__, line); \ } \ } while (0); #define IRO_DEBUG_CLEAR(obj, type) \ memset((obj), 0xFF, sizeof(type)) #else -#define IRO_ASSERT(expr) ((void) 0) +#define IRO_ASSERT(line, expr) ((void) 0) #define IRO_DEBUG_CLEAR(obj, type) ((void) 0) #endif @@ -222,8 +222,7 @@ inline void PTFList_RemoveAll(PTFList *ptfList); inline StackElement *StackElement_New(void) { StackElement *stackElement = IRO_malloc(sizeof(StackElement)); -#line 103 - IRO_ASSERT(stackElement != NULL); + IRO_ASSERT(103, stackElement != NULL); #ifdef IRO_DEBUG stackElement->proc = NULL; stackElement->ptf = NULL; @@ -234,23 +233,21 @@ inline StackElement *StackElement_New(void) { } inline void StackElement_Delete(StackElement *stackElement) { -#line 117 - IRO_ASSERT(stackElement != NULL); - IRO_ASSERT(stackElement->proc == NULL); - IRO_ASSERT(stackElement->ptf == NULL); - IRO_ASSERT(stackElement->map == NULL); - IRO_ASSERT(stackElement->funcCall == NULL); + IRO_ASSERT(117, stackElement != NULL); + IRO_ASSERT(118, stackElement->proc == NULL); + IRO_ASSERT(119, stackElement->ptf == NULL); + IRO_ASSERT(120, stackElement->map == NULL); + IRO_ASSERT(121, stackElement->funcCall == NULL); IRO_DEBUG_CLEAR(stackElement, sizeof(StackElement)); IRO_free(stackElement); } inline void StackElement_Init(StackElement *stackElement, Object *proc, PartialTransferFunction *ptf, ParamMappingFunction *map, IROLinear *funcCall) { -#line 131 - IRO_ASSERT(stackElement != NULL); - IRO_ASSERT(proc != NULL); - IRO_ASSERT(ptf != NULL); - IRO_ASSERT(map != NULL); - IRO_ASSERT(funcCall != NULL); + IRO_ASSERT(131, stackElement != NULL); + IRO_ASSERT(132, proc != NULL); + IRO_ASSERT(133, ptf != NULL); + IRO_ASSERT(134, map != NULL); + IRO_ASSERT(135, funcCall != NULL); stackElement->proc = proc; stackElement->ptf = ptf; stackElement->map = map; @@ -258,15 +255,13 @@ inline void StackElement_Init(StackElement *stackElement, Object *proc, PartialT } inline void StackElement_Copy(StackElement *dest, StackElement *src) { -#line 145 - IRO_ASSERT(dest != NULL); - IRO_ASSERT(src != NULL); + IRO_ASSERT(145, dest != NULL); + IRO_ASSERT(146, src != NULL); StackElement_Init(dest, src->proc, src->ptf, src->map, src->funcCall); } inline void StackElement_Term(StackElement *stackElement) { -#line 156 - IRO_ASSERT(stackElement != NULL); + IRO_ASSERT(156, stackElement != NULL); #ifdef IRO_DEBUG stackElement->proc = NULL; stackElement->ptf = NULL; @@ -276,46 +271,39 @@ inline void StackElement_Term(StackElement *stackElement) { } inline void *StackElement_sub_48A780(StackElement *stackElement) { -#line 213 - IRO_ASSERT(stackElement != NULL); + IRO_ASSERT(213, stackElement != NULL); return stackElement->proc; } inline Boolean StackRelated_sub_48A760(void *key1, void *key2) { -#line 220 - IRO_ASSERT(key1 != NULL); - IRO_ASSERT(key2 != NULL); + IRO_ASSERT(220, key1 != NULL); + IRO_ASSERT(221, key2 != NULL); return key1 == key2; } inline Object *StackElement_proc(StackElement *stackElement) { -#line 228 - IRO_ASSERT(stackElement != NULL); + IRO_ASSERT(228, stackElement != NULL); return stackElement->proc; } inline PartialTransferFunction *StackElement_ptf(StackElement *stackElement) { -#line 235 - IRO_ASSERT(stackElement != NULL); + IRO_ASSERT(235, stackElement != NULL); return stackElement->ptf; } inline ParamMappingFunction *StackElement_map(StackElement *stackElement) { -#line 242 - IRO_ASSERT(stackElement != NULL); + IRO_ASSERT(242, stackElement != NULL); return stackElement->map; } inline IROLinear *StackElement_funcCall(StackElement *stackElement) { -#line 249 - IRO_ASSERT(stackElement != NULL); + IRO_ASSERT(249, stackElement != NULL); return stackElement->funcCall; } inline Stack *Stack_New(void) { Stack *stack = IRO_malloc(sizeof(Stack)); -#line 265 - IRO_ASSERT(stack != NULL); + IRO_ASSERT(265, stack != NULL); #ifdef IRO_DEBUG stack->top = NULL; stack->next = NULL; @@ -324,17 +312,15 @@ inline Stack *Stack_New(void) { } inline void Stack_Delete(Stack *stack) { -#line 277 - IRO_ASSERT(stack != NULL); - IRO_ASSERT(stack->top == NULL); - IRO_ASSERT(stack->next == NULL); + IRO_ASSERT(277, stack != NULL); + IRO_ASSERT(278, stack->top == NULL); + IRO_ASSERT(279, stack->next == NULL); IRO_DEBUG_CLEAR(stack, sizeof(Stack)); IRO_free(stack); } inline void Stack_Init(Stack *stack) { -#line 289 - IRO_ASSERT(stack != NULL); + IRO_ASSERT(289, stack != NULL); stack->top = NULL; stack->next = NULL; } @@ -342,9 +328,8 @@ inline void Stack_Init(Stack *stack) { inline void Stack_Term(Stack **stackPtr) { StackElement *stackElement; -#line 299 - IRO_ASSERT(stackPtr != NULL); - IRO_ASSERT(*stackPtr != NULL); + IRO_ASSERT(299, stackPtr != NULL); + IRO_ASSERT(300, *stackPtr != NULL); while ((*stackPtr)->top) { stackElement = Stack_sub_48A5B0(stackPtr); @@ -357,9 +342,8 @@ inline void Stack_sub_48A660(Stack **stackPtr, StackElement *stackElement) { StackElement *newElement; Stack *newStack; -#line 315 - IRO_ASSERT(stackPtr != NULL); - IRO_ASSERT(*stackPtr != NULL); + IRO_ASSERT(315, stackPtr != NULL); + IRO_ASSERT(316, *stackPtr != NULL); newElement = StackElement_New(); StackElement_Copy(newElement, stackElement); @@ -371,17 +355,15 @@ inline void Stack_sub_48A660(Stack **stackPtr, StackElement *stackElement) { } inline StackElement *Stack_Top(Stack **stackPtr) { -#line 331 - IRO_ASSERT(stackPtr != NULL); - IRO_ASSERT(*stackPtr != NULL); + IRO_ASSERT(331, stackPtr != NULL); + IRO_ASSERT(332, *stackPtr != NULL); return (*stackPtr)->top; } inline Stack *Stack_Next(Stack **stackPtr) { -#line 343 - IRO_ASSERT(stackPtr != NULL); - IRO_ASSERT(*stackPtr != NULL); + IRO_ASSERT(343, stackPtr != NULL); + IRO_ASSERT(344, *stackPtr != NULL); return (*stackPtr)->next; } @@ -389,9 +371,8 @@ inline Stack *Stack_Next(Stack **stackPtr) { inline StackElement *Stack_sub_48A5B0(Stack **stackPtr) { StackElement *stackElement; -#line 357 - IRO_ASSERT(stackPtr != NULL); - IRO_ASSERT(*stackPtr != NULL); + IRO_ASSERT(357, stackPtr != NULL); + IRO_ASSERT(358, *stackPtr != NULL); stackElement = (*stackPtr)->top; if (stackElement) { @@ -408,9 +389,8 @@ inline StackElement *Stack_sub_48A5B0(Stack **stackPtr) { inline StackElement *Stack_sub_48A710(Stack **stackPtr, void *key) { Stack *stack; -#line 379 - IRO_ASSERT(stackPtr != NULL); - IRO_ASSERT(key != NULL); + IRO_ASSERT(379, stackPtr != NULL); + IRO_ASSERT(380, key != NULL); for (stack = *stackPtr; stack; stack = stack->next) { if (stack->top) { @@ -426,8 +406,7 @@ inline ObjectSet *ObjectSet_New(void) { ObjectSet *procList; procList = IRO_malloc(sizeof(ObjectSet)); -#line 439 - IRO_ASSERT(procList != NULL); + IRO_ASSERT(439, procList != NULL); #ifdef IRO_DEBUG procList->proc = NULL; procList->otherProcs = NULL; @@ -436,24 +415,21 @@ inline ObjectSet *ObjectSet_New(void) { } inline void ObjectSet_Delete(ObjectSet *procList) { -#line 451 - IRO_ASSERT(procList != NULL); - IRO_ASSERT(procList->proc == NULL); - IRO_ASSERT(procList->otherProcs == NULL); + IRO_ASSERT(451, procList != NULL); + IRO_ASSERT(452, procList->proc == NULL); + IRO_ASSERT(453, procList->otherProcs == NULL); IRO_DEBUG_CLEAR(procList, sizeof(ObjectSet)); IRO_free(procList); } inline void ObjectSet_Init(ObjectSet *procList) { -#line 463 - IRO_ASSERT(procList != NULL); + IRO_ASSERT(463, procList != NULL); procList->proc = NULL; procList->otherProcs = NULL; } inline void ObjectSet_Term(ObjectSet *procList) { -#line 481 - IRO_ASSERT(procList != NULL); + IRO_ASSERT(481, procList != NULL); ObjectSet_RemoveAll(procList); #ifdef IRO_DEBUG procList->proc = NULL; @@ -462,10 +438,9 @@ inline void ObjectSet_Term(ObjectSet *procList) { } inline void ObjectSet_ForEach(ObjectSet *procList, void (*action)(Object *, void *), void *refcon) { -#line 528 - IRO_ASSERT(procList != NULL); - IRO_ASSERT(action != NULL); - IRO_ASSERT(refcon == NULL || refcon != NULL); + IRO_ASSERT(528, procList != NULL); + IRO_ASSERT(529, action != NULL); + IRO_ASSERT(530, refcon == NULL || refcon != NULL); while (procList && procList->proc) { action(procList->proc, refcon); @@ -474,9 +449,8 @@ inline void ObjectSet_ForEach(ObjectSet *procList, void (*action)(Object *, void } inline Object *ObjectSet_sub_485020(ObjectSet *procList, Object *proc) { -#line 540 - IRO_ASSERT(procList != NULL); - IRO_ASSERT(proc != NULL); + IRO_ASSERT(540, procList != NULL); + IRO_ASSERT(541, proc != NULL); while (procList && procList->proc) { if (procList->proc == proc) return procList->proc; @@ -486,16 +460,14 @@ inline Object *ObjectSet_sub_485020(ObjectSet *procList, Object *proc) { } inline Object *ObjectSet_FindFirst(ObjectSet *procList) { -#line 552 - IRO_ASSERT(procList != NULL); + IRO_ASSERT(552, procList != NULL); return procList->proc; } inline int ObjectSet_Count(ObjectSet *procList) { int count; -#line 552 - IRO_ASSERT(procList != NULL); + IRO_ASSERT(561, procList != NULL); count = 0; while (procList && procList->proc) { @@ -509,9 +481,8 @@ inline int ObjectSet_Count(ObjectSet *procList) { inline void ObjectSet_sub_486800(ObjectSet *procList, Object *proc) { ObjectSet *newProcList; -#line 574 - IRO_ASSERT(procList != NULL); - IRO_ASSERT(proc != NULL); + IRO_ASSERT(574, procList != NULL); + IRO_ASSERT(575, proc != NULL); if (procList->proc) { newProcList = ObjectSet_New(); @@ -525,9 +496,8 @@ inline void ObjectSet_sub_486800(ObjectSet *procList, Object *proc) { } inline void ObjectSet_sub_4867D0(ObjectSet *procList, Object *proc) { -#line 592 - IRO_ASSERT(procList != NULL); - IRO_ASSERT(proc != NULL); + IRO_ASSERT(592, procList != NULL); + IRO_ASSERT(593, proc != NULL); if (!ObjectSet_sub_485020(procList, proc)) ObjectSet_sub_486800(procList, proc); @@ -537,9 +507,8 @@ inline void ObjectSet_Remove(ObjectSet *procList, Object *proc) { ObjectSet *prev; ObjectSet *tmp; -#line 605 - IRO_ASSERT(procList != NULL); - IRO_ASSERT(proc != NULL); + IRO_ASSERT(605, procList != NULL); + IRO_ASSERT(606, proc != NULL); prev = NULL; while (procList && procList->proc) { @@ -571,33 +540,29 @@ inline void ObjectSet_Remove(ObjectSet *procList, Object *proc) { } inline void ObjectSet_RemoveAll(ObjectSet *procList) { -#line 645 - IRO_ASSERT(procList != NULL); + IRO_ASSERT(645, procList != NULL); while (procList && procList->proc) ObjectSet_Remove(procList, procList->proc); } inline void ObjectSet_AddSetAction(Object *proc, void *refcon) { -#line 655 - IRO_ASSERT(proc != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(655, proc != NULL); + IRO_ASSERT(656, refcon != NULL); ObjectSet_sub_4867D0(refcon, proc); } inline void ObjectSet_SimpleAddSetAction(Object *proc, void *refcon) { -#line 663 - IRO_ASSERT(proc != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(663, proc != NULL); + IRO_ASSERT(664, refcon != NULL); ObjectSet_sub_486800(refcon, proc); } inline void ObjectSet_sub_48C590(ObjectSet *dest, ObjectSet *src) { -#line 671 - IRO_ASSERT(dest != NULL); - IRO_ASSERT(src != NULL); + IRO_ASSERT(671, dest != NULL); + IRO_ASSERT(672, src != NULL); if (dest->proc) ObjectSet_ForEach(src, ObjectSet_AddSetAction, dest); @@ -606,17 +571,15 @@ inline void ObjectSet_sub_48C590(ObjectSet *dest, ObjectSet *src) { } inline void ObjectSet_RemoveSetAction(Object *proc, void *refcon) { -#line 682 - IRO_ASSERT(proc != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(682, proc != NULL); + IRO_ASSERT(683, refcon != NULL); ObjectSet_Remove(refcon, proc); } inline void ObjectSet_removeiter_sub_48C890(ObjectSet *dest, ObjectSet *src) { -#line 690 - IRO_ASSERT(dest != NULL); - IRO_ASSERT(src != NULL); + IRO_ASSERT(690, dest != NULL); + IRO_ASSERT(691, src != NULL); ObjectSet_ForEach(src, ObjectSet_RemoveSetAction, dest); } @@ -624,9 +587,8 @@ inline void ObjectSet_removeiter_sub_48C890(ObjectSet *dest, ObjectSet *src) { inline Boolean ObjectSet_sub_484FA0(ObjectSet *os1, ObjectSet *os2) { ObjectSet *scan; -#line 700 - IRO_ASSERT(os1 != NULL); - IRO_ASSERT(os2 != NULL); + IRO_ASSERT(700, os1 != NULL); + IRO_ASSERT(701, os2 != NULL); if (os1 == os2) return 1; @@ -647,8 +609,7 @@ inline Boolean ObjectSet_sub_484FA0(ObjectSet *os1, ObjectSet *os2) { inline ExtendedParam *ExtendedParam_New(void) { ExtendedParam *ep = IRO_malloc(sizeof(ExtendedParam)); -#line 755 - IRO_ASSERT(ep != NULL); + IRO_ASSERT(755, ep != NULL); #ifdef IRO_DEBUG ep->objectSet = NULL; #endif @@ -656,18 +617,17 @@ inline ExtendedParam *ExtendedParam_New(void) { } inline void ExtendedParam_Delete(ExtendedParam *ep) { - IRO_ASSERT(ep != NULL); - IRO_ASSERT(ep->objectSet == NULL); + IRO_ASSERT(762, ep != NULL); + IRO_ASSERT(763, ep->objectSet == NULL); IRO_DEBUG_CLEAR(ep, sizeof(ExtendedParam)); IRO_free(ep); } inline void ExtendedParam_Init(ExtendedParam *ep, Object *obj) { -#line 777 - IRO_ASSERT(ep != NULL); - IRO_ASSERT(obj != NULL); - IRO_ASSERT(obj->extParam == NULL); - IRO_ASSERT(stExtendedParamNum < ((uint32) -1) / 2 - 1); + IRO_ASSERT(777, ep != NULL); + IRO_ASSERT(778, obj != NULL); + IRO_ASSERT(779, obj->extParam == NULL); + IRO_ASSERT(780, stExtendedParamNum < ((uint32) -1) / 2 - 1); ep->objectSet = ObjectSet_New(); ObjectSet_Init(ep->objectSet); @@ -682,7 +642,7 @@ inline void ExtendedParam_TermAction(Object *obj, void *refcon) { } inline void ExtendedParam_Term(ExtendedParam *ep) { - IRO_ASSERT(ep != NULL); + IRO_ASSERT(800, ep != NULL); ObjectSet_ForEach(ep->objectSet, ExtendedParam_TermAction, NULL); ObjectSet_Term(ep->objectSet); @@ -693,11 +653,10 @@ inline void ExtendedParam_Term(ExtendedParam *ep) { } inline Boolean ExtendedParams_Equal(ExtendedParam *ep1, ExtendedParam *ep2) { -#line 841 - IRO_ASSERT(ep1 != NULL); - IRO_ASSERT(ep2 != NULL); - IRO_ASSERT(ep1->objectSet != NULL); - IRO_ASSERT(ep2->objectSet != NULL); + IRO_ASSERT(841, ep1 != NULL); + IRO_ASSERT(842, ep2 != NULL); + IRO_ASSERT(843, ep1->objectSet != NULL); + IRO_ASSERT(844, ep2->objectSet != NULL); if (ep1 == ep2) return 1; @@ -706,17 +665,15 @@ inline Boolean ExtendedParams_Equal(ExtendedParam *ep1, ExtendedParam *ep2) { } inline ExtendedParam *ExtendedParam_FindByObject(Object *obj) { -#line 856 - IRO_ASSERT(obj != NULL); + IRO_ASSERT(856, obj != NULL); return obj->extParam; } inline void ExtendedParam_sub_4867B0(ExtendedParam *ep, Object *obj) { -#line 863 - IRO_ASSERT(ep != NULL); - IRO_ASSERT(ep->objectSet != NULL); - IRO_ASSERT(obj != NULL); + IRO_ASSERT(863, ep != NULL); + IRO_ASSERT(864, ep->objectSet != NULL); + IRO_ASSERT(865, obj != NULL); ObjectSet_sub_4867D0(ep->objectSet, obj); obj->extParam = ep; @@ -727,25 +684,22 @@ inline void ExtendedParam_RemoveObjectSetAction(Object *object, void *refcon) { } inline void EP_sub_48C850(ExtendedParam *ep, ObjectSet *objSet) { -#line 888 - IRO_ASSERT(ep != NULL); - IRO_ASSERT(ep->objectSet != NULL); - IRO_ASSERT(objSet != NULL); + IRO_ASSERT(888, ep != NULL); + IRO_ASSERT(889, ep->objectSet != NULL); + IRO_ASSERT(890, objSet != NULL); ObjectSet_removeiter_sub_48C890(ep->objectSet, objSet); ObjectSet_ForEach(objSet, ExtendedParam_RemoveObjectSetAction, NULL); } inline ObjectSet *ExtendedParam_objectSet(ExtendedParam *ep) { -#line 898 - IRO_ASSERT(ep != NULL); + IRO_ASSERT(898, ep != NULL); return ep->objectSet; } inline uint32 ExtendedParam_sub_489110(ExtendedParam *ep) { -#line 905 - IRO_ASSERT(ep != NULL); + IRO_ASSERT(905, ep != NULL); return ep->x4; } @@ -753,8 +707,7 @@ inline uint32 ExtendedParam_sub_489110(ExtendedParam *ep) { inline ExtendedParamSet *AllocsExtParamSet_sub_4876C0(void) { ExtendedParamSet *epList = IRO_malloc(sizeof(ExtendedParamSet)); -#line 924 - IRO_ASSERT(epList != NULL); + IRO_ASSERT(924, epList != NULL); #ifdef IRO_DEBUG epList->ep = NULL; epList->otherEps = NULL; @@ -763,24 +716,21 @@ inline ExtendedParamSet *AllocsExtParamSet_sub_4876C0(void) { } inline void FreesExtParamSet_sub_48CAE0(ExtendedParamSet *epList) { -#line 936 - IRO_ASSERT(epList != NULL); - IRO_ASSERT(epList->ep == NULL); - IRO_ASSERT(epList->otherEps == NULL); + IRO_ASSERT(936, epList != NULL); + IRO_ASSERT(937, epList->ep == NULL); + IRO_ASSERT(938, epList->otherEps == NULL); IRO_DEBUG_CLEAR(epList, sizeof(ExtendedParamSet)); IRO_free(epList); } inline void InitsExtParamSet_sub_4876A0(ExtendedParamSet *epList) { -#line 948 - IRO_ASSERT(epList != NULL); + IRO_ASSERT(948, epList != NULL); epList->ep = NULL; epList->otherEps = NULL; } inline void TermsExtParamSet_sub_48CB00(ExtendedParamSet *epList) { -#line 966 - IRO_ASSERT(epList != NULL); + IRO_ASSERT(966, epList != NULL); ExtendedParamSet_RemoveAll(epList); #ifdef IRO_DEBUG epList->ep = NULL; @@ -789,9 +739,8 @@ inline void TermsExtParamSet_sub_48CB00(ExtendedParamSet *epList) { } inline void MaybeWalkExtParamSet_sub_48CBE0(ExtendedParamSet *epList, void (*action)(ExtendedParam *, void *), void *refcon) { -#line 1010 - IRO_ASSERT(epList != NULL); - IRO_ASSERT(action != NULL); + IRO_ASSERT(1010, epList != NULL); + IRO_ASSERT(1011, action != NULL); while (epList && epList->ep) { action(epList->ep, refcon); @@ -800,9 +749,8 @@ inline void MaybeWalkExtParamSet_sub_48CBE0(ExtendedParamSet *epList, void (*act } inline ExtendedParam *ExtParamSet_sub_4876D0(ExtendedParamSet *epList, ExtendedParam *ep) { -#line 1022 - IRO_ASSERT(epList != NULL); - IRO_ASSERT(ep != NULL); + IRO_ASSERT(1022, epList != NULL); + IRO_ASSERT(1023, ep != NULL); while (epList && epList->ep) { if (epList->ep == ep) @@ -814,9 +762,8 @@ inline ExtendedParam *ExtParamSet_sub_4876D0(ExtendedParamSet *epList, ExtendedP } inline void ExtParamSet_sub_487660(ExtendedParamSet *epList, ExtendedParam *ep) { -#line 1056 - IRO_ASSERT(epList != NULL); - IRO_ASSERT(ep != NULL); + IRO_ASSERT(1056, epList != NULL); + IRO_ASSERT(1057, ep != NULL); if (epList->ep) { ExtendedParamSet *newSet = AllocsExtParamSet_sub_4876C0(); @@ -830,9 +777,8 @@ inline void ExtParamSet_sub_487660(ExtendedParamSet *epList, ExtendedParam *ep) } inline void ExtParamSet_sub_487630(ExtendedParamSet *epList, ExtendedParam *ep) { -#line 1076 - IRO_ASSERT(epList != NULL); - IRO_ASSERT(ep != NULL); + IRO_ASSERT(1076, epList != NULL); + IRO_ASSERT(1077, ep != NULL); if (!ExtParamSet_sub_4876D0(epList, ep)) ExtParamSet_sub_487660(epList, ep); @@ -842,9 +788,8 @@ inline void ExtendedParamSet_Remove(ExtendedParamSet *epList, ExtendedParam *ep) ExtendedParamSet *prev; ExtendedParamSet *tmp; -#line 1089 - IRO_ASSERT(epList != NULL); - IRO_ASSERT(ep != NULL); + IRO_ASSERT(1089, epList != NULL); + IRO_ASSERT(1090, ep != NULL); prev = NULL; while (epList && epList->ep) { @@ -876,8 +821,7 @@ inline void ExtendedParamSet_Remove(ExtendedParamSet *epList, ExtendedParam *ep) } inline void ExtendedParamSet_RemoveAll(ExtendedParamSet *epList) { -#line 1129 - IRO_ASSERT(epList != NULL); + IRO_ASSERT(1129, epList != NULL); while (epList && epList->ep) ExtendedParamSet_Remove(epList, epList->ep); @@ -886,8 +830,7 @@ inline void ExtendedParamSet_RemoveAll(ExtendedParamSet *epList) { inline PAHeapBlock *CreateUniqueHeapAlloc_sub_486420(void) { PAHeapBlock *hb = IRO_malloc(sizeof(PAHeapBlock)); -#line 1225 - IRO_ASSERT(hb != NULL); + IRO_ASSERT(1225, hb != NULL); #ifdef IRO_DEBUG hb->parent = NULL; #endif @@ -895,16 +838,14 @@ inline PAHeapBlock *CreateUniqueHeapAlloc_sub_486420(void) { } inline void InitUniqueHeapAlloc_sub_486410(PAHeapBlock *hb, IROLinear *nd) { -#line 1247 - IRO_ASSERT(hb != NULL); + IRO_ASSERT(1247, hb != NULL); hb->x0 = nd; } inline Boolean PAHeapBlocks_Equal(PAHeapBlock *hb1, PAHeapBlock *hb2) { -#line 1296 - IRO_ASSERT(hb1 != NULL); - IRO_ASSERT(hb2 != NULL); + IRO_ASSERT(1296, hb1 != NULL); + IRO_ASSERT(1297, hb2 != NULL); return (hb1 == hb2) || (hb1->x0 == hb2->x0); } @@ -912,8 +853,7 @@ inline Boolean PAHeapBlocks_Equal(PAHeapBlock *hb1, PAHeapBlock *hb2) { inline PALocalVar *PALocalVar_New(void) { PALocalVar *local = IRO_malloc(sizeof(PALocalVar)); -#line 1333 - IRO_ASSERT(local != NULL); + IRO_ASSERT(1333, local != NULL); #ifdef IRO_DEBUG local->parent = NULL; local->nextSibling = NULL; @@ -922,9 +862,8 @@ inline PALocalVar *PALocalVar_New(void) { } inline void PALocalVar_InitByObject(PALocalVar *local, Object *obj) { -#line 1357 - IRO_ASSERT(local != NULL); - IRO_ASSERT(obj != NULL); + IRO_ASSERT(1357, local != NULL); + IRO_ASSERT(1358, obj != NULL); local->x0 = obj; if (obj->name && obj->name->name) { @@ -936,9 +875,8 @@ inline void PALocalVar_InitByObject(PALocalVar *local, Object *obj) { } inline void PALocalVar_InitByName(PALocalVar *local, char *name) { -#line 1372 - IRO_ASSERT(local != NULL); - IRO_ASSERT(name != NULL); + IRO_ASSERT(1372, local != NULL); + IRO_ASSERT(1373, name != NULL); local->x0 = NULL; local->x4 = IRO_malloc(strlen(name) + 1); @@ -946,9 +884,8 @@ inline void PALocalVar_InitByName(PALocalVar *local, char *name) { } inline Boolean PALocalVars_Equal(PALocalVar *local1, PALocalVar *local2) { -#line 1419 - IRO_ASSERT(local1 == NULL || local1 != NULL); - IRO_ASSERT(local2 == NULL || local2 != NULL); + IRO_ASSERT(1419, local1 == NULL || local1 != NULL); + IRO_ASSERT(1420, local2 == NULL || local2 != NULL); if (local1 == local2) return 1; @@ -964,30 +901,26 @@ inline Boolean PALocalVars_Equal(PALocalVar *local1, PALocalVar *local2) { } inline void PALocalVar_SetSth_sub_4847C0(PALocalVar *local, Object *obj) { -#line 1436 - IRO_ASSERT(local != NULL); - IRO_ASSERT(obj == NULL || obj != NULL); + IRO_ASSERT(1436, local != NULL); + IRO_ASSERT(1437, obj == NULL || obj != NULL); local->x0 = obj; } inline Object *PALocalVar_Get0_sub_4847E0(PALocalVar *local) { -#line 1444 - IRO_ASSERT(local != NULL); + IRO_ASSERT(1444, local != NULL); return local->x0; } inline char *PALocalVar_Get4_sub_4847D0(PALocalVar *local) { -#line 1451 - IRO_ASSERT(local != NULL); + IRO_ASSERT(1451, local != NULL); return local->x4; } inline PAMemoryBlock *PAMemoryBlock_New(void) { PAMemoryBlock *mb = IRO_malloc(sizeof(PAMemoryBlock)); -#line 1491 - IRO_ASSERT(mb != NULL); + IRO_ASSERT(1491, mb != NULL); #ifdef IRO_DEBUG mb->kind = PAMEMORYBLOCKKIND_INVALID; #endif @@ -995,16 +928,14 @@ inline PAMemoryBlock *PAMemoryBlock_New(void) { } inline void PAMemoryBlock_Delete(PAMemoryBlock *mb) { -#line 1502 - IRO_ASSERT(mb != NULL); - IRO_ASSERT(mb->kind == PAMEMORYBLOCKKIND_INVALID); + IRO_ASSERT(1502, mb != NULL); + IRO_ASSERT(1503, mb->kind == PAMEMORYBLOCKKIND_INVALID); IRO_free(mb); } inline void PAMemoryBlock_Init(PAMemoryBlock *mb, PAMemoryBlockKind kind, void *thing) { -#line 1513 - IRO_ASSERT(mb != NULL); - IRO_ASSERT(thing == NULL || thing != NULL); + IRO_ASSERT(1513, mb != NULL); + IRO_ASSERT(1514, thing == NULL || thing != NULL); mb->kind = kind; switch (mb->kind) { @@ -1024,14 +955,12 @@ inline void PAMemoryBlock_Init(PAMemoryBlock *mb, PAMemoryBlockKind kind, void * mb->u.x6 = (void *) thing; break; default: -#line 1535 - CError_FATAL(); + CError_FATAL(1535); } } inline void PAMemoryBlock_Term(PAMemoryBlock *mb) { -#line 1552 - IRO_ASSERT(mb != NULL); + IRO_ASSERT(1552, mb != NULL); #ifdef IRO_DEBUG mb->kind = PAMEMORYBLOCKKIND_INVALID; @@ -1039,9 +968,8 @@ inline void PAMemoryBlock_Term(PAMemoryBlock *mb) { } inline Boolean MemoryBlocks_Equal(PAMemoryBlock *mb1, PAMemoryBlock *mb2) { -#line 1657 - IRO_ASSERT(mb1 == NULL || mb1 != NULL); - IRO_ASSERT(mb2 == NULL || mb2 != NULL); + IRO_ASSERT(1657, mb1 == NULL || mb1 != NULL); + IRO_ASSERT(1658, mb2 == NULL || mb2 != NULL); if (mb1 == mb2) return 1; @@ -1061,22 +989,19 @@ inline Boolean MemoryBlocks_Equal(PAMemoryBlock *mb1, PAMemoryBlock *mb2) { case PAMEMORYBLOCKKIND_6: return mb1->u.x6 == mb2->u.x6; default: -#line 1684 - CError_FATAL(); + CError_FATAL(1684); return 0; } } inline PAMemoryBlockKind PAMemoryBlock_kind(PAMemoryBlock *mb) { -#line 1692 - IRO_ASSERT(mb != NULL); + IRO_ASSERT(1692, mb != NULL); return mb->kind; } inline void *PAMemoryBlock_thing(PAMemoryBlock *mb) { -#line 1699 - IRO_ASSERT(mb != NULL); + IRO_ASSERT(1699, mb != NULL); switch (mb->kind) { case PAMEMORYBLOCKKIND_EXTENDEDPARAM: @@ -1090,8 +1015,7 @@ inline void *PAMemoryBlock_thing(PAMemoryBlock *mb) { case PAMEMORYBLOCKKIND_6: return mb->u.x6; default: -#line 1719 - CError_FATAL(); + CError_FATAL(1719); return NULL; } } @@ -1099,8 +1023,7 @@ inline void *PAMemoryBlock_thing(PAMemoryBlock *mb) { inline LocationSet *LocationSet_New(void) { LocationSet *ls = IRO_malloc(sizeof(LocationSet)); -#line 1767 - IRO_ASSERT(ls != NULL); + IRO_ASSERT(1767, ls != NULL); #ifdef IRO_DEBUG ls->block = NULL; ls->rtype = NULL; @@ -1111,23 +1034,21 @@ inline LocationSet *LocationSet_New(void) { } inline void LocationSet_Delete(LocationSet *ls) { -#line 1781 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(ls != stUnknownLs); - IRO_ASSERT(ls->block == NULL); - IRO_ASSERT(CInt64_IsZero(&ls->u.known.field)); - IRO_ASSERT(ls->u.known.stride == 0); - IRO_ASSERT(ls->rtype == NULL); + IRO_ASSERT(1781, ls != NULL); + IRO_ASSERT(1782, ls != stUnknownLs); + IRO_ASSERT(1783, ls->block == NULL); + IRO_ASSERT(1784, CInt64_IsZero(&ls->u.known.field)); + IRO_ASSERT(1785, ls->u.known.stride == 0); + IRO_ASSERT(1786, ls->rtype == NULL); IRO_DEBUG_CLEAR(ls, sizeof(LocationSet)); IRO_free(ls); } inline void LocationSet_InitKnown(LocationSet *ls, PAMemoryBlock *block, CInt64 field, UInt32 stride, Type *rtype) { -#line 1796 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(ls != stUnknownLs); - IRO_ASSERT(block != NULL); - IRO_ASSERT(rtype == NULL || rtype != NULL); + IRO_ASSERT(1796, ls != NULL); + IRO_ASSERT(1797, ls != stUnknownLs); + IRO_ASSERT(1798, block != NULL); + IRO_ASSERT(1799, rtype == NULL || rtype != NULL); ls->block = block; ls->rtype = rtype; ls->u.known.field = field; @@ -1135,12 +1056,11 @@ inline void LocationSet_InitKnown(LocationSet *ls, PAMemoryBlock *block, CInt64 } inline void LocationSet_InitUnknown(LocationSet *ls, Type *rtype, PAMemoryBlock *restriction, LocationSet *bitfieldOf) { -#line 1809 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(ls != stUnknownLs); - IRO_ASSERT(rtype == NULL || rtype != NULL); - IRO_ASSERT(restriction == NULL || restriction != NULL); - IRO_ASSERT(bitfieldOf == NULL || bitfieldOf != NULL); + IRO_ASSERT(1809, ls != NULL); + IRO_ASSERT(1810, ls != stUnknownLs); + IRO_ASSERT(1811, rtype == NULL || rtype != NULL); + IRO_ASSERT(1812, restriction == NULL || restriction != NULL); + IRO_ASSERT(1813, bitfieldOf == NULL || bitfieldOf != NULL); LocationSet_Copy(ls, stUnknownLs); ls->rtype = rtype; @@ -1154,9 +1074,8 @@ inline void LocationSet_InitUnknown(LocationSet *ls, Type *rtype, PAMemoryBlock } inline void LocationSet_Copy(LocationSet *dest, LocationSet *src) { -#line 1829 - IRO_ASSERT(src != NULL); - IRO_ASSERT(dest != NULL); + IRO_ASSERT(1829, src != NULL); + IRO_ASSERT(1830, dest != NULL); dest->block = src->block; dest->rtype = src->rtype; @@ -1176,9 +1095,8 @@ inline void LocationSet_Copy(LocationSet *dest, LocationSet *src) { } inline void LocationSet_Term(LocationSet *ls) { -#line 1857 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(ls != stUnknownLs); + IRO_ASSERT(1857, ls != NULL); + IRO_ASSERT(1858, ls != stUnknownLs); #ifdef IRO_DEBUG if (LocationSet_IsUnknown(ls) && ls->u.unknown.bitfieldOf) { @@ -1196,11 +1114,10 @@ inline Boolean LocationSets_Overlap(LocationSet *ls1, Type *rtype1, LocationSet Boolean isUnknown1, isUnknown2; PAMemoryBlock *restriction1, *restriction2; -#line 1974 - IRO_ASSERT(ls1 != NULL); - IRO_ASSERT(rtype1 == NULL || rtype1 != NULL); - IRO_ASSERT(ls2 != NULL); - IRO_ASSERT(rtype2 == NULL || rtype2 != NULL); + IRO_ASSERT(1974, ls1 != NULL); + IRO_ASSERT(1975, rtype1 == NULL || rtype1 != NULL); + IRO_ASSERT(1976, ls2 != NULL); + IRO_ASSERT(1977, rtype2 == NULL || rtype2 != NULL); if (ls1 == ls2) return 1; @@ -1296,9 +1213,8 @@ inline Boolean LocationSets_Overlap(LocationSet *ls1, Type *rtype1, LocationSet } inline Boolean LocationSets_Equal(LocationSet *ls1, LocationSet *ls2) { -#line 2080 - IRO_ASSERT(ls1 != NULL); - IRO_ASSERT(ls2 != NULL); + IRO_ASSERT(2080, ls1 != NULL); + IRO_ASSERT(2081, ls2 != NULL); return (ls1 == ls2) || @@ -1319,9 +1235,8 @@ inline Boolean LocationSets_Equal(LocationSet *ls1, LocationSet *ls2) { } inline Boolean LocationSets_LookupCompatible(LocationSet *ls1, LocationSet *ls2) { -#line 2119 - IRO_ASSERT(ls1 != NULL); - IRO_ASSERT(ls2 != NULL); + IRO_ASSERT(2119, ls1 != NULL); + IRO_ASSERT(2120, ls2 != NULL); if ( (ls1 == ls2) || @@ -1363,11 +1278,10 @@ inline Boolean LocationSet_Contains(LocationSet *ls1, Type *rtype1, LocationSet CInt64 longsize1; CInt64 longsize2; -#line 2168 - IRO_ASSERT(ls1 != NULL); - IRO_ASSERT(ls2 != NULL); - IRO_ASSERT(rtype1 != NULL); - IRO_ASSERT(rtype2 != NULL); + IRO_ASSERT(2168, ls1 != NULL); + IRO_ASSERT(2169, ls2 != NULL); + IRO_ASSERT(2170, rtype1 != NULL); + IRO_ASSERT(2171, rtype2 != NULL); if (ls1 == ls2) return 1; @@ -1401,8 +1315,7 @@ inline Boolean LocationSet_Contains(LocationSet *ls1, Type *rtype1, LocationSet } inline Boolean LocationSet_IsUnknown(LocationSet *ls) { -#line 2233 - IRO_ASSERT(ls != NULL); + IRO_ASSERT(2233, ls != NULL); return (ls == stUnknownLs) || (ls->block == stUnknownMb); } @@ -1417,73 +1330,64 @@ inline Boolean LocationSet_sub_48AF30(LocationSet *ls) { } inline void LocationSet_SetRtype(LocationSet *ls, Type *rtype) { -#line 2263 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(ls != stUnknownLs); - IRO_ASSERT(rtype != NULL); + IRO_ASSERT(2263, ls != NULL); + IRO_ASSERT(2264, ls != stUnknownLs); + IRO_ASSERT(2265, rtype != NULL); ls->rtype = rtype; } inline void SetsLocationSetField_sub_4851B0(LocationSet *ls, CInt64 field) { -#line 2272 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(!LocationSet_IsUnknown(ls)); + IRO_ASSERT(2272, ls != NULL); + IRO_ASSERT(2273, !LocationSet_IsUnknown(ls)); ls->u.known.field = field; } inline void SetsLocationSetStride_sub_4852D0(LocationSet *ls, SInt32 stride) { -#line 2280 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(!LocationSet_IsUnknown(ls)); + IRO_ASSERT(2280, ls != NULL); + IRO_ASSERT(2281, !LocationSet_IsUnknown(ls)); ls->u.known.stride = stride; } inline PAMemoryBlock *LocationSet_block(LocationSet *ls) { -#line 2298 - IRO_ASSERT(ls != NULL); + IRO_ASSERT(2298, ls != NULL); return ls->block; } inline Type *LocationSet_rtype(LocationSet *ls) { -#line 2306 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(ls != stUnknownLs); + IRO_ASSERT(2306, ls != NULL); + IRO_ASSERT(2307, ls != stUnknownLs); return ls->rtype; } inline CInt64 LocationSet_field(LocationSet *ls) { -#line 2314 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(!LocationSet_IsUnknown(ls)); + IRO_ASSERT(2314, ls != NULL); + IRO_ASSERT(2315, !LocationSet_IsUnknown(ls)); return ls->u.known.field; } inline UInt32 LocationSet_stride(LocationSet *ls) { -#line 2322 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(!LocationSet_IsUnknown(ls)); + IRO_ASSERT(2322, ls != NULL); + IRO_ASSERT(2323, !LocationSet_IsUnknown(ls)); return ls->u.known.stride; } inline PAMemoryBlock *LocationSet_restriction(LocationSet *ls) { -#line 2330 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(LocationSet_IsUnknown(ls)); + IRO_ASSERT(2330, ls != NULL); + IRO_ASSERT(2331, LocationSet_IsUnknown(ls)); return ls->u.unknown.restriction; } inline LocationSet *LocationSet_bitfieldOf(LocationSet *ls) { -#line 2338 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(LocationSet_IsUnknown(ls)); + IRO_ASSERT(2338, ls != NULL); + IRO_ASSERT(2339, LocationSet_IsUnknown(ls)); return ls->u.unknown.bitfieldOf; } @@ -1491,8 +1395,7 @@ inline LocationSet *LocationSet_bitfieldOf(LocationSet *ls) { inline LocationSetSet *LocationSetSet_New() { LocationSetSet *lss = IRO_malloc(sizeof(LocationSetSet)); -#line 2356 - IRO_ASSERT(lss != NULL); + IRO_ASSERT(2356, lss != NULL); #ifdef IRO_DEBUG lss->loc = NULL; lss->otherLocs = NULL; @@ -1502,18 +1405,16 @@ inline LocationSetSet *LocationSetSet_New() { } inline void LocationSetSet_Delete(LocationSetSet *lss) { -#line 2369 - IRO_ASSERT(lss != NULL); - IRO_ASSERT(lss->loc == NULL); - IRO_ASSERT(lss->otherLocs == NULL); - IRO_ASSERT(lss->count == 0); + IRO_ASSERT(2369, lss != NULL); + IRO_ASSERT(2370, lss->loc == NULL); + IRO_ASSERT(2371, lss->otherLocs == NULL); + IRO_ASSERT(2372, lss->count == 0); IRO_DEBUG_CLEAR(lss, sizeof(LocationSetSet)); IRO_free(lss); } inline void LocationSetSet_Init(LocationSetSet *lss) { -#line 2382 - IRO_ASSERT(lss != NULL); + IRO_ASSERT(2382, lss != NULL); lss->loc = NULL; lss->otherLocs = NULL; @@ -1521,9 +1422,8 @@ inline void LocationSetSet_Init(LocationSetSet *lss) { } inline void LocationSetSet_Copy(LocationSetSet *dest, LocationSetSet *src) { -#line 2391 - IRO_ASSERT(dest != NULL); - IRO_ASSERT(src != NULL); + IRO_ASSERT(2391, dest != NULL); + IRO_ASSERT(2392, src != NULL); dest->loc = NULL; dest->otherLocs = NULL; @@ -1532,8 +1432,7 @@ inline void LocationSetSet_Copy(LocationSetSet *dest, LocationSetSet *src) { } inline void LocationSetSet_Term(LocationSetSet *lss) { -#line 2402 - IRO_ASSERT(lss != NULL); + IRO_ASSERT(2402, lss != NULL); LocationSetSet_RemoveAll(lss); @@ -1545,10 +1444,9 @@ inline void LocationSetSet_Term(LocationSetSet *lss) { } inline void LocationSetSet_ForEach(LocationSetSet *lss, void (*action)(LocationSet *, void *), void *refcon) { -#line 2446 - IRO_ASSERT(lss != NULL); - IRO_ASSERT(action != NULL); - IRO_ASSERT(refcon == NULL || refcon != NULL); + IRO_ASSERT(2446, lss != NULL); + IRO_ASSERT(2447, action != NULL); + IRO_ASSERT(2448, refcon == NULL || refcon != NULL); while (lss && lss->loc) { action(lss->loc, refcon); @@ -1557,9 +1455,8 @@ inline void LocationSetSet_ForEach(LocationSetSet *lss, void (*action)(LocationS } inline LocationSet *LocationSetSet_Find(LocationSetSet *lss, LocationSet *ls) { -#line 2458 - IRO_ASSERT(lss != NULL); - IRO_ASSERT(ls != NULL); + IRO_ASSERT(2458, lss != NULL); + IRO_ASSERT(2459, ls != NULL); while (lss && lss->loc) { if (LocationSets_Equal(lss->loc, ls)) @@ -1571,8 +1468,7 @@ inline LocationSet *LocationSetSet_Find(LocationSetSet *lss, LocationSet *ls) { } inline LocationSet *LocationSetSet_FindUnknown(LocationSetSet *lss) { -#line 2470 - IRO_ASSERT(lss != NULL); + IRO_ASSERT(2470, lss != NULL); if (!lss->loc) return stUnknownLs; @@ -1587,15 +1483,13 @@ inline LocationSet *LocationSetSet_FindUnknown(LocationSetSet *lss) { } inline LocationSet *LocationSetSet_FindFirst(LocationSetSet *lss) { -#line 2498 - IRO_ASSERT(lss != NULL); + IRO_ASSERT(2498, lss != NULL); return lss->loc; } inline int LocationSetSet_Count(LocationSetSet *lss) { -#line 2505 - IRO_ASSERT(lss != NULL); + IRO_ASSERT(2505, lss != NULL); return lss->count; } @@ -1606,9 +1500,8 @@ inline void LocationSetSet_RemoveAllWithMemoryBlock(LocationSetSet *lss, PAMemor LocationSetSet *next; LocationSetSet *tmp; -#line 2514 - IRO_ASSERT(lss != NULL); - IRO_ASSERT(block != NULL); + IRO_ASSERT(2514, lss != NULL); + IRO_ASSERT(2515, block != NULL); first = lss; prev = NULL; @@ -1649,9 +1542,8 @@ inline void LocationSetSet_RemoveAllWithMemoryBlock(LocationSetSet *lss, PAMemor } inline void LocationSetSet_SimpleAdd(LocationSetSet *lss, LocationSet *ls) { -#line 2572 - IRO_ASSERT(lss != NULL); - IRO_ASSERT(ls != NULL); + IRO_ASSERT(2572, lss != NULL); + IRO_ASSERT(2573, ls != NULL); if (!LocationSet_IsUnknown(ls) && lss->count < 4) { LocationSet *ls2; @@ -1692,9 +1584,8 @@ inline void LocationSetSet_SimpleAdd(LocationSetSet *lss, LocationSet *ls) { } inline void LocationSetSet_Add(LocationSetSet *lss, LocationSet *ls) { -#line 2622 - IRO_ASSERT(lss != NULL); - IRO_ASSERT(ls != NULL); + IRO_ASSERT(2622, lss != NULL); + IRO_ASSERT(2623, ls != NULL); if (!lss->loc || (!LocationSet_IsUnknown(lss->loc) && !LocationSetSet_Find(lss, ls))) { if (!LocationSet_IsUnknown(ls) && ls->u.known.stride) @@ -1706,11 +1597,10 @@ inline void LocationSetSet_Add(LocationSetSet *lss, LocationSet *ls) { inline void LocationSetSet_AddUnknown(LocationSetSet *lss, Type *rtype, PAMemoryBlock *restriction, LocationSet *bitfieldOf) { LocationSet *ls; -#line 2643 - IRO_ASSERT(lss != NULL); - IRO_ASSERT(rtype == NULL || rtype != NULL); - IRO_ASSERT(restriction == NULL || restriction != NULL); - IRO_ASSERT(bitfieldOf == NULL || bitfieldOf != NULL); + IRO_ASSERT(2643, lss != NULL); + IRO_ASSERT(2644, rtype == NULL || rtype != NULL); + IRO_ASSERT(2645, restriction == NULL || restriction != NULL); + IRO_ASSERT(2646, bitfieldOf == NULL || bitfieldOf != NULL); ls = LocationSet_New(); LocationSet_InitUnknown(ls, rtype, restriction, bitfieldOf); @@ -1724,9 +1614,8 @@ inline void LocationSetSet_Remove(LocationSetSet *lss, LocationSet *ls) { LocationSetSet *first; LocationSetSet *tmp; -#line 2659 - IRO_ASSERT(lss != NULL); - IRO_ASSERT(ls != NULL); + IRO_ASSERT(2659, lss != NULL); + IRO_ASSERT(2660, ls != NULL); first = lss; prev = NULL; @@ -1765,33 +1654,29 @@ inline void LocationSetSet_Remove(LocationSetSet *lss, LocationSet *ls) { } inline void LocationSetSet_RemoveAll(LocationSetSet *lss) { -#line 2707 - IRO_ASSERT(lss != NULL); + IRO_ASSERT(2707, lss != NULL); while (lss && lss->loc) LocationSetSet_Remove(lss, lss->loc); } inline void LocationSetSet_AddSetAction(LocationSet *ls, void *refcon) { -#line 2717 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(2717, ls != NULL); + IRO_ASSERT(2718, refcon != NULL); LocationSetSet_Add((LocationSetSet *) refcon, ls); } inline void LocationSetSet_SimpleAddSetAction(LocationSet *ls, void *refcon) { -#line 2725 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(2725, ls != NULL); + IRO_ASSERT(2726, refcon != NULL); LocationSetSet_SimpleAdd((LocationSetSet *) refcon, ls); } inline void LocationSetSet_AddSet(LocationSetSet *dest, LocationSetSet *src) { -#line 2733 - IRO_ASSERT(dest != NULL); - IRO_ASSERT(src != NULL); + IRO_ASSERT(2733, dest != NULL); + IRO_ASSERT(2734, src != NULL); if (dest->count) LocationSetSet_ForEach(src, LocationSetSet_AddSetAction, dest); @@ -1800,25 +1685,22 @@ inline void LocationSetSet_AddSet(LocationSetSet *dest, LocationSetSet *src) { } inline void LocationSetSet_RemoveSetAction(LocationSet *ls, void *refcon) { -#line 2744 - IRO_ASSERT(ls != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(2744, ls != NULL); + IRO_ASSERT(2745, refcon != NULL); LocationSetSet_Remove((LocationSetSet *) refcon, ls); } inline void LocationSetSet_sub_488700(LocationSetSet *dest, LocationSetSet *src) { -#line 2752 - IRO_ASSERT(dest != NULL); - IRO_ASSERT(src != NULL); + IRO_ASSERT(2752, dest != NULL); + IRO_ASSERT(2753, src != NULL); LocationSetSet_ForEach(src, LocationSetSet_RemoveSetAction, dest); } inline Boolean LocationSetSets_Equal(LocationSetSet *lss1, LocationSetSet *lss2) { -#line 2826 - IRO_ASSERT(lss1 != NULL); - IRO_ASSERT(lss2 != NULL); + IRO_ASSERT(2826, lss1 != NULL); + IRO_ASSERT(2827, lss2 != NULL); if (lss1 == lss2) return 1; @@ -1837,8 +1719,7 @@ inline Boolean LocationSetSets_Equal(LocationSetSet *lss1, LocationSetSet *lss2) inline ParamMapping *ParamMapping_New(void) { ParamMapping *pm = IRO_malloc(sizeof(ParamMapping)); -#line 2885 - IRO_ASSERT(pm != NULL); + IRO_ASSERT(2885, pm != NULL); #ifdef IRO_DEBUG pm->actual = NULL; pm->formal = NULL; @@ -1848,18 +1729,16 @@ inline ParamMapping *ParamMapping_New(void) { } inline void ParamMapping_Delete(ParamMapping *pm) { -#line 2898 - IRO_ASSERT(pm != NULL); - IRO_ASSERT(pm->actual == NULL); - IRO_ASSERT(pm->formal == NULL); - IRO_ASSERT(pm->extended == NULL); + IRO_ASSERT(2898, pm != NULL); + IRO_ASSERT(2899, pm->actual == NULL); + IRO_ASSERT(2900, pm->formal == NULL); + IRO_ASSERT(2901, pm->extended == NULL); IRO_DEBUG_CLEAR(pm, sizeof(ParamMapping)); IRO_free(pm); } inline void ParamMapping_Init_PROBABLY(ParamMapping *pm, IROLinear *actual, Object *formal, ExtendedParam *extended) { -#line 2911 - IRO_ASSERT(pm != NULL); + IRO_ASSERT(2911, pm != NULL); pm->actual = actual; pm->formal = formal; @@ -1867,9 +1746,8 @@ inline void ParamMapping_Init_PROBABLY(ParamMapping *pm, IROLinear *actual, Obje } inline void ParamMapping_Copy(ParamMapping *dest, ParamMapping *src) { -#line 2920 - IRO_ASSERT(src != NULL); - IRO_ASSERT(dest != NULL); + IRO_ASSERT(2920, src != NULL); + IRO_ASSERT(2921, dest != NULL); dest->actual = src->actual; dest->formal = src->formal; @@ -1877,8 +1755,7 @@ inline void ParamMapping_Copy(ParamMapping *dest, ParamMapping *src) { } inline void ParamMapping_Term(ParamMapping *pm) { -#line 2933 - IRO_ASSERT(pm != NULL); + IRO_ASSERT(2933, pm != NULL); #ifdef IRO_DEBUG pm->actual = NULL; @@ -1888,22 +1765,19 @@ inline void ParamMapping_Term(ParamMapping *pm) { } inline void ParamMapping_SetExtended(ParamMapping *pm, ExtendedParam *ep) { -#line 2992 - IRO_ASSERT(pm != NULL); + IRO_ASSERT(2992, pm != NULL); pm->extended = ep; } inline IROLinear *ParamMapping_actual(ParamMapping *pm) { -#line 2999 - IRO_ASSERT(pm != NULL); + IRO_ASSERT(2999, pm != NULL); return pm->actual; } inline ExtendedParam *ParamMapping_extended(ParamMapping *pm) { -#line 3011 - IRO_ASSERT(pm != NULL); + IRO_ASSERT(3011, pm != NULL); return pm->extended; } @@ -1911,8 +1785,7 @@ inline ExtendedParam *ParamMapping_extended(ParamMapping *pm) { inline ParamMappingFunction *ParamMappingFunction_New(void) { ParamMappingFunction *pmf = IRO_malloc(sizeof(ParamMappingFunction)); -#line 3026 - IRO_ASSERT(pmf != NULL); + IRO_ASSERT(3026, pmf != NULL); #ifdef IRO_DEBUG pmf->mapping = NULL; pmf->otherMappings = NULL; @@ -1921,26 +1794,23 @@ inline ParamMappingFunction *ParamMappingFunction_New(void) { } inline void ParamMappingFunction_Delete(ParamMappingFunction *pmf) { -#line 3039 - IRO_ASSERT(pmf != NULL); - IRO_ASSERT(pmf->mapping == NULL); - IRO_ASSERT(pmf->otherMappings == NULL); + IRO_ASSERT(3039, pmf != NULL); + IRO_ASSERT(3040, pmf->mapping == NULL); + IRO_ASSERT(3041, pmf->otherMappings == NULL); IRO_DEBUG_CLEAR(pmf, sizeof(ParamMappingFunction)); IRO_free(pmf); } inline void ParamMappingFunction_Init(ParamMappingFunction *pmf) { -#line 3050 - IRO_ASSERT(pmf != NULL); + IRO_ASSERT(3050, pmf != NULL); pmf->mapping = NULL; pmf->otherMappings = NULL; } inline void ParamMappingFunction_Copy(ParamMappingFunction *dest, ParamMappingFunction *src) { -#line 3058 - IRO_ASSERT(src != NULL); - IRO_ASSERT(dest != NULL); + IRO_ASSERT(3058, src != NULL); + IRO_ASSERT(3059, dest != NULL); dest->mapping = NULL; dest->otherMappings = NULL; @@ -1948,8 +1818,7 @@ inline void ParamMappingFunction_Copy(ParamMappingFunction *dest, ParamMappingFu } inline void ParamMappingFunction_Term(ParamMappingFunction *pmf) { -#line 3068 - IRO_ASSERT(pmf != NULL); + IRO_ASSERT(3068, pmf != NULL); ParamMappingFunction_RemoveAll(pmf); @@ -1960,10 +1829,9 @@ inline void ParamMappingFunction_Term(ParamMappingFunction *pmf) { } inline void pmf_sub_487C70(ParamMappingFunction *pmf, void (*action)(ParamMapping *, void *), void *refcon) { -#line 3111 - IRO_ASSERT(pmf != NULL); - IRO_ASSERT(action != NULL); - IRO_ASSERT(refcon == NULL || refcon != NULL); + IRO_ASSERT(3111, pmf != NULL); + IRO_ASSERT(3112, action != NULL); + IRO_ASSERT(3113, refcon == NULL || refcon != NULL); while (pmf && pmf->mapping) { action(pmf->mapping, refcon); @@ -1972,9 +1840,8 @@ inline void pmf_sub_487C70(ParamMappingFunction *pmf, void (*action)(ParamMappin } inline ParamMapping *ParamMappingFunction_FindMappingByFormal(ParamMappingFunction *pmf, Object *formal) { -#line 3123 - IRO_ASSERT(pmf != NULL); - IRO_ASSERT(formal != NULL); + IRO_ASSERT(3123, pmf != NULL); + IRO_ASSERT(3124, formal != NULL); while (pmf && pmf->mapping) { if (pmf->mapping->formal == formal) @@ -1988,9 +1855,8 @@ inline ParamMapping *ParamMappingFunction_FindMappingByFormal(ParamMappingFuncti inline void Pmf_Add_sub_486610(ParamMappingFunction *pmf, ParamMapping *mapping) { ParamMapping *existing; -#line 3138 - IRO_ASSERT(pmf != NULL); - IRO_ASSERT(mapping != NULL); + IRO_ASSERT(3138, pmf != NULL); + IRO_ASSERT(3139, mapping != NULL); existing = ParamMappingFunction_FindMappingByFormal(pmf, mapping->formal); if (!existing) { @@ -2014,9 +1880,8 @@ inline void ParamMappingFunction_Remove(ParamMappingFunction *pmf, ParamMapping ParamMappingFunction *prev; ParamMappingFunction *tmp; -#line 3170 - IRO_ASSERT(pmf != NULL); - IRO_ASSERT(mapping != NULL); + IRO_ASSERT(3170, pmf != NULL); + IRO_ASSERT(3171, mapping != NULL); prev = NULL; while (pmf && pmf->mapping) { @@ -2051,25 +1916,22 @@ inline void ParamMappingFunction_Remove(ParamMappingFunction *pmf, ParamMapping } inline void ParamMappingFunction_RemoveAll(ParamMappingFunction *pmf) { -#line 3213 - IRO_ASSERT(pmf != NULL); + IRO_ASSERT(3213, pmf != NULL); while (pmf && pmf->mapping) ParamMappingFunction_Remove(pmf, pmf->mapping); } inline void ParamMappingFunction_AddFunctionAction(ParamMapping *mapping, void *refcon) { -#line 3223 - IRO_ASSERT(mapping != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(3223, mapping != NULL); + IRO_ASSERT(3224, refcon != NULL); Pmf_Add_sub_486610((ParamMappingFunction *) refcon, mapping); } inline void ParamMappingFunction_AddAllMaybe_sub_487C50(ParamMappingFunction *dest, ParamMappingFunction *src) { -#line 3231 - IRO_ASSERT(dest != NULL); - IRO_ASSERT(src != NULL); + IRO_ASSERT(3231, dest != NULL); + IRO_ASSERT(3232, src != NULL); pmf_sub_487C70(src, ParamMappingFunction_AddFunctionAction, dest); } @@ -2077,8 +1939,7 @@ inline void ParamMappingFunction_AddAllMaybe_sub_487C50(ParamMappingFunction *de inline PointsToEntry *PointsToEntry_New(void) { PointsToEntry *pte = IRO_malloc(sizeof(PointsToEntry)); -#line 3288 - IRO_ASSERT(pte != NULL); + IRO_ASSERT(3288, pte != NULL); #ifdef IRO_DEBUG pte->loc = NULL; pte->locs = NULL; @@ -2087,20 +1948,18 @@ inline PointsToEntry *PointsToEntry_New(void) { } inline void PointsToEntry_Delete(PointsToEntry *pte) { -#line 3300 - IRO_ASSERT(pte != NULL); - IRO_ASSERT(pte->loc == NULL); - IRO_ASSERT(pte->locs == NULL); + IRO_ASSERT(3300, pte != NULL); + IRO_ASSERT(3301, pte->loc == NULL); + IRO_ASSERT(3302, pte->locs == NULL); IRO_DEBUG_CLEAR(pte, sizeof(PointsToEntry)); IRO_free(pte); } inline void PointsToEntry_Init(PointsToEntry *pte, LocationSet *loc, LocationSetSet *locs) { -#line 3312 - IRO_ASSERT(pte != NULL); - IRO_ASSERT(loc != NULL); - IRO_ASSERT(!LocationSet_IsUnknown(loc)); - IRO_ASSERT(locs != NULL); + IRO_ASSERT(3312, pte != NULL); + IRO_ASSERT(3313, loc != NULL); + IRO_ASSERT(3314, !LocationSet_IsUnknown(loc)); + IRO_ASSERT(3315, locs != NULL); pte->loc = LocationSet_New(); LocationSet_Copy(pte->loc, loc); @@ -2110,16 +1969,14 @@ inline void PointsToEntry_Init(PointsToEntry *pte, LocationSet *loc, LocationSet } inline void PointsToEntry_Copy(PointsToEntry *dest, PointsToEntry *src) { -#line 3325 - IRO_ASSERT(src != NULL); - IRO_ASSERT(dest != NULL); + IRO_ASSERT(3325, src != NULL); + IRO_ASSERT(3326, dest != NULL); PointsToEntry_Init(dest, src->loc, src->locs); } inline void PointsToEntry_Term(PointsToEntry *pte) { -#line 3333 - IRO_ASSERT(pte != NULL); + IRO_ASSERT(3333, pte != NULL); LocationSet_Term(pte->loc); LocationSet_Delete(pte->loc); @@ -2133,9 +1990,8 @@ inline void PointsToEntry_Term(PointsToEntry *pte) { } inline Boolean PointsToEntries_Equal(PointsToEntry *pte1, PointsToEntry *pte2) { -#line 3381 - IRO_ASSERT(pte1 != NULL); - IRO_ASSERT(pte2 != NULL); + IRO_ASSERT(3381, pte1 != NULL); + IRO_ASSERT(3382, pte2 != NULL); if (pte1 == pte2) return 1; @@ -2144,15 +2000,13 @@ inline Boolean PointsToEntries_Equal(PointsToEntry *pte1, PointsToEntry *pte2) { } inline LocationSet *PointsToEntry_loc(PointsToEntry *pte) { -#line 3407 - IRO_ASSERT(pte != NULL); + IRO_ASSERT(3407, pte != NULL); return pte->loc; } inline LocationSetSet *PointsToEntry_locs(PointsToEntry *pte) { -#line 3414 - IRO_ASSERT(pte != NULL); + IRO_ASSERT(3414, pte != NULL); return pte->locs; } @@ -2160,8 +2014,7 @@ inline LocationSetSet *PointsToEntry_locs(PointsToEntry *pte) { inline PointsToFunction *PointsToFunction_New(void) { PointsToFunction *pointsToFunc = IRO_malloc(sizeof(PointsToFunction)); -#line 3430 - IRO_ASSERT(pointsToFunc != NULL); + IRO_ASSERT(3430, pointsToFunc != NULL); #ifdef IRO_DEBUG pointsToFunc->pte = NULL; pointsToFunc->otherPtes = NULL; @@ -2170,26 +2023,23 @@ inline PointsToFunction *PointsToFunction_New(void) { } inline void PointsToFunction_Delete(PointsToFunction *pointsToFunc) { -#line 3442 - IRO_ASSERT(pointsToFunc != NULL); - IRO_ASSERT(pointsToFunc->pte == NULL); - IRO_ASSERT(pointsToFunc->otherPtes == NULL); + IRO_ASSERT(3442, pointsToFunc != NULL); + IRO_ASSERT(3443, pointsToFunc->pte == NULL); + IRO_ASSERT(3444, pointsToFunc->otherPtes == NULL); IRO_DEBUG_CLEAR(pointsToFunc, sizeof(PointsToFunction)); IRO_free(pointsToFunc); } inline void PointsToFunction_Init(PointsToFunction *pointsToFunc) { -#line 3454 - IRO_ASSERT(pointsToFunc != NULL); + IRO_ASSERT(3454, pointsToFunc != NULL); pointsToFunc->pte = NULL; pointsToFunc->otherPtes = NULL; } inline void PointsToFunction_Copy(PointsToFunction *dest, PointsToFunction *src) { -#line 3462 - IRO_ASSERT(src != NULL); - IRO_ASSERT(dest != NULL); + IRO_ASSERT(3462, src != NULL); + IRO_ASSERT(3463, dest != NULL); dest->pte = NULL; dest->otherPtes = NULL; @@ -2197,8 +2047,7 @@ inline void PointsToFunction_Copy(PointsToFunction *dest, PointsToFunction *src) } inline void PointsToFunction_Term(PointsToFunction *pointsToFunc) { -#line 3472 - IRO_ASSERT(pointsToFunc != NULL); + IRO_ASSERT(3472, pointsToFunc != NULL); PointsToFunction_RemoveAll(pointsToFunc); @@ -2209,10 +2058,9 @@ inline void PointsToFunction_Term(PointsToFunction *pointsToFunc) { } inline void PointsToFunction_ForEach(PointsToFunction *pointsToFunc, void (*action)(PointsToEntry *, void *), void *refcon) { -#line 3515 - IRO_ASSERT(pointsToFunc != NULL); - IRO_ASSERT(action != NULL); - IRO_ASSERT(refcon == NULL || refcon != NULL); + IRO_ASSERT(3515, pointsToFunc != NULL); + IRO_ASSERT(3516, action != NULL); + IRO_ASSERT(3517, refcon == NULL || refcon != NULL); while (pointsToFunc && pointsToFunc->pte) { action(pointsToFunc->pte, refcon); @@ -2221,9 +2069,8 @@ inline void PointsToFunction_ForEach(PointsToFunction *pointsToFunc, void (*acti } inline PointsToEntry *PointsToFunction_FindByLocationSet(PointsToFunction *pointsToFunc, LocationSet *ls) { -#line 3527 - IRO_ASSERT(pointsToFunc != NULL); - IRO_ASSERT(ls != NULL); + IRO_ASSERT(3527, pointsToFunc != NULL); + IRO_ASSERT(3528, ls != NULL); while (pointsToFunc && pointsToFunc->pte) { if (LocationSets_Equal(pointsToFunc->pte->loc, ls)) @@ -2235,16 +2082,14 @@ inline PointsToEntry *PointsToFunction_FindByLocationSet(PointsToFunction *point } inline PointsToEntry *PointsToFunction_FindFirst(PointsToFunction *pointsToFunc) { -#line 3539 - IRO_ASSERT(pointsToFunc != NULL); + IRO_ASSERT(3539, pointsToFunc != NULL); return pointsToFunc->pte; } inline PointsToEntry *PointsToFunction_FindByLookupCompatibleLocationSet(PointsToFunction *pointsToFunc, LocationSet *ls) { -#line 3546 - IRO_ASSERT(pointsToFunc != NULL); - IRO_ASSERT(ls != NULL); + IRO_ASSERT(3546, pointsToFunc != NULL); + IRO_ASSERT(3547, ls != NULL); while (pointsToFunc && pointsToFunc->pte) { if (ls->u.known.stride) { @@ -2260,10 +2105,9 @@ inline PointsToEntry *PointsToFunction_FindByLookupCompatibleLocationSet(PointsT } inline PointsToEntry *PointsToFunction_FindContainingLocationSet(PointsToFunction *pointsToFunc, LocationSet *ls, Type *rtype) { -#line 3565 - IRO_ASSERT(pointsToFunc != NULL); - IRO_ASSERT(ls != NULL); - IRO_ASSERT(rtype != NULL); + IRO_ASSERT(3565, pointsToFunc != NULL); + IRO_ASSERT(3566, ls != NULL); + IRO_ASSERT(3567, rtype != NULL); while (pointsToFunc && pointsToFunc->pte) { if (pointsToFunc->pte->locs->loc && !LocationSet_IsUnknown(pointsToFunc->pte->locs->loc)) { @@ -2284,18 +2128,16 @@ inline void PointsToFunction_RemoveOverlappingLocations(PointsToFunction *points PointsToFunction *next; PointsToFunction *tmp; -#line 3601 - IRO_ASSERT(pointsToFunc != NULL); - IRO_ASSERT(pte != NULL); - IRO_ASSERT(pte->locs != NULL); + IRO_ASSERT(3601, pointsToFunc != NULL); + IRO_ASSERT(3602, pte != NULL); + IRO_ASSERT(3603, pte->locs != NULL); if (pte->locs->loc && pte->locs->loc != stUnknownLs) rtype1 = pte->locs->loc->rtype; else rtype1 = NULL; ls = pte->loc; -#line 3614 - IRO_ASSERT(ls != NULL); + IRO_ASSERT(3614, ls != NULL); prev = NULL; while (pointsToFunc && pointsToFunc->pte) { @@ -2352,15 +2194,14 @@ inline Boolean ShouldAddNewPointsToEntryToFunction(PointsToFunction *pointsToFun Boolean flag2; Boolean flag3; -#line 3675 - IRO_ASSERT(pointsToFunc != NULL); - IRO_ASSERT(pte != NULL); - IRO_ASSERT(pte->locs != NULL); - IRO_ASSERT(PointsToFunction_FindByLookupCompatibleLocationSet(pointsToFunc, pte->loc) == NULL); - IRO_ASSERT((unknown = LocationSetSet_FindFirst(pte->locs)) != NULL); - IRO_ASSERT(LocationSet_IsUnknown(unknown)); - IRO_ASSERT(LocationSet_bitfieldOf(unknown) == NULL); - IRO_ASSERT(LocationSet_restriction(unknown) == NULL); + IRO_ASSERT(3675, pointsToFunc != NULL); + IRO_ASSERT(3676, pte != NULL); + IRO_ASSERT(3677, pte->locs != NULL); + IRO_ASSERT(3678, PointsToFunction_FindByLookupCompatibleLocationSet(pointsToFunc, pte->loc) == NULL); + IRO_ASSERT(3679, (unknown = LocationSetSet_FindFirst(pte->locs)) != NULL); + IRO_ASSERT(3680, LocationSet_IsUnknown(unknown)); + IRO_ASSERT(3681, LocationSet_bitfieldOf(unknown) == NULL); + IRO_ASSERT(3682, LocationSet_restriction(unknown) == NULL); if (pte->locs->loc && pte->locs->loc != stUnknownLs) rtype1 = pte->locs->loc->rtype; @@ -2368,8 +2209,7 @@ inline Boolean ShouldAddNewPointsToEntryToFunction(PointsToFunction *pointsToFun rtype1 = NULL; loc = pte->loc; -#line 3693 - IRO_ASSERT(loc != NULL); + IRO_ASSERT(3693, loc != NULL); isKnown = !LocationSet_IsUnknown(loc); if (isKnown) @@ -2410,9 +2250,8 @@ inline Boolean ShouldAddNewPointsToEntryToFunction(PointsToFunction *pointsToFun inline Boolean PointsToFunction_SimpleAdd(PointsToFunction *pointsToFunc, PointsToEntry *pte) { PointsToEntry *newPTE; -#line 3741 - IRO_ASSERT(pointsToFunc != NULL); - IRO_ASSERT(pte != NULL); + IRO_ASSERT(3741, pointsToFunc != NULL); + IRO_ASSERT(3742, pte != NULL); newPTE = PointsToEntry_New(); PointsToEntry_Copy(newPTE, pte); @@ -2428,9 +2267,8 @@ inline Boolean PointsToFunction_SimpleAdd(PointsToFunction *pointsToFunc, Points } inline Boolean PointsToFunction_Add(PointsToFunction *pointsToFunc, PointsToEntry *pte) { -#line 3766 - IRO_ASSERT(pointsToFunc != NULL); - IRO_ASSERT(pte != NULL); + IRO_ASSERT(3766, pointsToFunc != NULL); + IRO_ASSERT(3767, pte != NULL); if (!PointsToFunction_FindByLookupCompatibleLocationSet(pointsToFunc, pte->loc)) { LocationSet *ls; @@ -2449,9 +2287,8 @@ inline Boolean PointsToFunction_Add(PointsToFunction *pointsToFunc, PointsToEntr inline Boolean PointsToFunction_AddWithoutChecking(PointsToFunction *pointsToFunc, PointsToEntry *pte) { LocationSet *ls; -#line 3793 - IRO_ASSERT(pointsToFunc != NULL); - IRO_ASSERT(pte != NULL); + IRO_ASSERT(3793, pointsToFunc != NULL); + IRO_ASSERT(3794, pte != NULL); if (!(ls = LocationSetSet_FindFirst(pte->locs)) || !LocationSet_IsUnknown(ls) || LocationSet_bitfieldOf(ls) || LocationSet_restriction(ls) || ShouldAddNewPointsToEntryToFunction(pointsToFunc, pte)) { @@ -2468,10 +2305,9 @@ inline void PointsToFunction_RemoveByLocationSet(PointsToFunction *pointsToFunc, PointsToFunction *prev; PointsToFunction *tmp; -#line 3170 - IRO_ASSERT(pointsToFunc != NULL); - IRO_ASSERT(ls != NULL); - IRO_ASSERT(!LocationSet_IsUnknown(ls)); + IRO_ASSERT(3170, pointsToFunc != NULL); + IRO_ASSERT(3171, ls != NULL); + IRO_ASSERT(3172, !LocationSet_IsUnknown(ls)); prev = NULL; while (pointsToFunc && pointsToFunc->pte) { @@ -2506,33 +2342,29 @@ inline void PointsToFunction_RemoveByLocationSet(PointsToFunction *pointsToFunc, } inline void PointsToFunction_RemoveAll(PointsToFunction *pointsToFunc) { -#line 3862 - IRO_ASSERT(pointsToFunc != NULL); + IRO_ASSERT(3862, pointsToFunc != NULL); while (pointsToFunc && pointsToFunc->pte) PointsToFunction_RemoveByLocationSet(pointsToFunc, pointsToFunc->pte->loc); } inline void PointsToFunction_AddFunctionAction(PointsToEntry *pte, void *refcon) { -#line 3872 - IRO_ASSERT(pte != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(3872, pte != NULL); + IRO_ASSERT(3873, refcon != NULL); PointsToFunction_Add((PointsToFunction *) refcon, pte); } inline void PointsToFunction_SimpleAddFunctionAction(PointsToEntry *pte, void *refcon) { -#line 3880 - IRO_ASSERT(pte != NULL); - IRO_ASSERT(refcon != NULL); + IRO_ASSERT(3880, pte != NULL); + IRO_ASSERT(3881, refcon != NULL); PointsToFunction_SimpleAdd((PointsToFunction *) refcon, pte); } inline void PointsToFunction_AddAllIGuess_sub_487D80(PointsToFunction *dest, PointsToFunction *src) { -#line 3888 - IRO_ASSERT(dest != NULL); - IRO_ASSERT(src != NULL); + IRO_ASSERT(3888, dest != NULL); + IRO_ASSERT(3889, src != NULL); if (dest->pte) PointsToFunction_ForEach(src, PointsToFunction_AddFunctionAction, dest); @@ -2589,9 +2421,8 @@ inline Boolean PointsToFunctions_Equal(PointsToFunction *pointsToFunc1, PointsTo PointsToFunction *scan; PointsToEntry *pte; -#line 3968 - IRO_ASSERT(pointsToFunc1 != NULL); - IRO_ASSERT(pointsToFunc2 != NULL); + IRO_ASSERT(3968, pointsToFunc1 != NULL); + IRO_ASSERT(3969, pointsToFunc2 != NULL); if (pointsToFunc1 == pointsToFunc2) return 1; @@ -2618,8 +2449,7 @@ inline Boolean PointsToFunctions_Match(PointsToFunction *pointsToFunc1, PointsTo inline PartialTransferFunction *PartialTransferFunction_New() { PartialTransferFunction *ptf = IRO_malloc(sizeof(PartialTransferFunction)); -#line 4110 - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(4110, ptf != NULL); #ifdef IRO_DEBUG ptf->initialPointsToFn = NULL; ptf->finalPointsToFn = NULL; @@ -2632,23 +2462,21 @@ inline PartialTransferFunction *PartialTransferFunction_New() { } inline void PartialTransferFunction_Delete(PartialTransferFunction *ptf) { -#line 4126 - IRO_ASSERT(ptf != NULL); - IRO_ASSERT(ptf->initialPointsToFn == NULL); - IRO_ASSERT(ptf->finalPointsToFn == NULL); - IRO_ASSERT(ptf->funcModifies == NULL); - IRO_ASSERT(ptf->context.nd == NULL); - IRO_ASSERT(ptf->context.ptf == NULL); - IRO_ASSERT(ptf->returnLocation == NULL); + IRO_ASSERT(4126, ptf != NULL); + IRO_ASSERT(4127, ptf->initialPointsToFn == NULL); + IRO_ASSERT(4128, ptf->finalPointsToFn == NULL); + IRO_ASSERT(4129, ptf->funcModifies == NULL); + IRO_ASSERT(4130, ptf->context.nd == NULL); + IRO_ASSERT(4131, ptf->context.ptf == NULL); + IRO_ASSERT(4132, ptf->returnLocation == NULL); IRO_DEBUG_CLEAR(ptf, sizeof(PartialTransferFunction)); IRO_free(ptf); } inline void PartialTransferFunction_Init(PartialTransferFunction *ptf, IROLinear *contextNd, PartialTransferFunction *contextPTF) { -#line 4142 - IRO_ASSERT(ptf != NULL); - IRO_ASSERT(contextNd != NULL); - IRO_ASSERT(contextPTF != NULL); + IRO_ASSERT(4142, ptf != NULL); + IRO_ASSERT(4143, contextNd != NULL); + IRO_ASSERT(4144, contextPTF != NULL); ptf->initialPointsToFn = PointsToFunction_New(); PointsToFunction_Init(ptf->initialPointsToFn); @@ -2667,9 +2495,8 @@ inline void PartialTransferFunction_Init(PartialTransferFunction *ptf, IROLinear } inline void PartialTransferFunction_Copy(PartialTransferFunction *dest, PartialTransferFunction *src) { -#line 4164 - IRO_ASSERT(src != NULL); - IRO_ASSERT(dest != NULL); + IRO_ASSERT(4164, src != NULL); + IRO_ASSERT(4165, dest != NULL); dest->initialPointsToFn = PointsToFunction_New(); PointsToFunction_Copy(dest->initialPointsToFn, src->initialPointsToFn); @@ -2691,8 +2518,7 @@ inline void PartialTransferFunction_Copy(PartialTransferFunction *dest, PartialT } inline void PartialTransferFunction_Term(PartialTransferFunction *ptf) { -#line 4190 - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(4190, ptf != NULL); PointsToFunction_Term(ptf->initialPointsToFn); PointsToFunction_Delete(ptf->initialPointsToFn); @@ -2719,29 +2545,25 @@ inline void PartialTransferFunction_Term(PartialTransferFunction *ptf) { } inline PointsToFunction *PartialTransferFunction_initialPointsToFn(PartialTransferFunction *ptf) { -#line 4221 - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(4221, ptf != NULL); return ptf->initialPointsToFn; } inline PointsToFunction *PartialTransferFunction_finalPointsToFn(PartialTransferFunction *ptf) { -#line 4227 - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(4227, ptf != NULL); return ptf->finalPointsToFn; } inline LocationSetSet *PTF_sub_48D750(PartialTransferFunction *ptf) { -#line 4233 - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(4233, ptf != NULL); return ptf->funcModifies; } inline LocationSet *PartialTransferFunction_returnLocation(PartialTransferFunction *ptf) { -#line 4249 - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(4249, ptf != NULL); if (!ptf->returnLocation) { PAMemoryBlock *block; @@ -2758,22 +2580,19 @@ inline LocationSet *PartialTransferFunction_returnLocation(PartialTransferFuncti } inline IROLinear *PTF_sub_48B980(PartialTransferFunction *ptf) { -#line 4265 - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(4265, ptf != NULL); return ptf->context.nd; } inline PartialTransferFunction *PTF_sub_48B970(PartialTransferFunction *ptf) { -#line 4271 - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(4271, ptf != NULL); return ptf->context.ptf; } inline void PartialTransferFunction_sub_48A610(PartialTransferFunction *ptf, Boolean value) { -#line 4298 - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(4298, ptf != NULL); ptf->x10 = (value != 0) ? 1 : 0; } @@ -2781,8 +2600,7 @@ inline void PartialTransferFunction_sub_48A610(PartialTransferFunction *ptf, Boo inline PTFList *PTFList_New(void) { PTFList *ptfList = IRO_malloc(sizeof(PTFList)); -#line 4393 - IRO_ASSERT(ptfList != NULL); + IRO_ASSERT(4393, ptfList != NULL); #ifdef IRO_DEBUG ptfList->ptf = NULL; ptfList->otherPTFs = NULL; @@ -2791,25 +2609,22 @@ inline PTFList *PTFList_New(void) { } inline void PTFList_Delete(PTFList *ptfList) { -#line 4405 - IRO_ASSERT(ptfList != NULL); - IRO_ASSERT(ptfList->ptf == NULL); - IRO_ASSERT(ptfList->otherPTFs == NULL); + IRO_ASSERT(4405, ptfList != NULL); + IRO_ASSERT(4406, ptfList->ptf == NULL); + IRO_ASSERT(4407, ptfList->otherPTFs == NULL); IRO_DEBUG_CLEAR(ptfList, sizeof(PTFList)); IRO_free(ptfList); } inline void PTFList_Init(PTFList *ptfList) { -#line 4417 - IRO_ASSERT(ptfList != NULL); + IRO_ASSERT(4417, ptfList != NULL); ptfList->ptf = NULL; ptfList->otherPTFs = NULL; } inline void PTFList_Term(PTFList *ptfList) { -#line 4435 - IRO_ASSERT(ptfList != NULL); + IRO_ASSERT(4435, ptfList != NULL); PTFList_RemoveAll(ptfList); @@ -2820,10 +2635,9 @@ inline void PTFList_Term(PTFList *ptfList) { } inline void PTFList_ForEach(PTFList *ptfList, void (*action)(PartialTransferFunction *, void *), void *refcon) { -#line 4478 - IRO_ASSERT(ptfList != NULL); - IRO_ASSERT(action != NULL); - IRO_ASSERT(refcon == NULL || refcon != NULL); + IRO_ASSERT(4478, ptfList != NULL); + IRO_ASSERT(4479, action != NULL); + IRO_ASSERT(4480, refcon == NULL || refcon != NULL); while (ptfList && ptfList->ptf) { action(ptfList->ptf, refcon); @@ -2832,9 +2646,8 @@ inline void PTFList_ForEach(PTFList *ptfList, void (*action)(PartialTransferFunc } inline PartialTransferFunction *PTFList_sub_48A0F0(PTFList *ptfList, PartialTransferFunction *ptf) { -#line 4490 - IRO_ASSERT(ptfList != NULL); - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(4490, ptfList != NULL); + IRO_ASSERT(4491, ptf != NULL); while (ptfList && ptfList->ptf) { if (ptfList->ptf == ptf) @@ -2847,16 +2660,14 @@ inline PartialTransferFunction *PTFList_sub_48A0F0(PTFList *ptfList, PartialTran } inline PartialTransferFunction *PTFList_FindFirst(PTFList *ptfList) { -#line 4502 - IRO_ASSERT(ptfList != NULL); + IRO_ASSERT(4502, ptfList != NULL); return ptfList->ptf; } inline void PTFList_sub_48A080(PTFList *ptfList, PartialTransferFunction *ptf) { -#line 4511 - IRO_ASSERT(ptfList != NULL); - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(4511, ptfList != NULL); + IRO_ASSERT(4512, ptf != NULL); if (ptfList->ptf) { PTFList *newList = PTFList_New(); @@ -2870,9 +2681,8 @@ inline void PTFList_sub_48A080(PTFList *ptfList, PartialTransferFunction *ptf) { } inline void PTFList_sub_48A050(PTFList *ptfList, PartialTransferFunction *ptf) { -#line 4529 - IRO_ASSERT(ptfList != NULL); - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(4529, ptfList != NULL); + IRO_ASSERT(4530, ptf != NULL); if (!PTFList_sub_48A0F0(ptfList, ptf)) PTFList_sub_48A080(ptfList, ptf); @@ -2882,9 +2692,8 @@ inline void PTFList_Remove(PTFList *ptfList, PartialTransferFunction *ptf) { PTFList *prev; PTFList *tmp; -#line 4542 - IRO_ASSERT(ptfList != NULL); - IRO_ASSERT(ptf != NULL); + IRO_ASSERT(4542, ptfList != NULL); + IRO_ASSERT(4543, ptf != NULL); prev = NULL; while (ptfList && ptfList->ptf) { @@ -2917,8 +2726,7 @@ inline void PTFList_Remove(PTFList *ptfList, PartialTransferFunction *ptf) { } inline void PTFList_RemoveAll(PTFList *ptfList) { -#line 4582 - IRO_ASSERT(ptfList != NULL); + IRO_ASSERT(4582, ptfList != NULL); while (ptfList && ptfList->ptf) PTFList_Remove(ptfList, ptfList->ptf); diff --git a/compiler_and_linker/unsorted/IroTransform.c b/compiler_and_linker/unsorted/IroTransform.c index 710f2d8..e63421b 100644 --- a/compiler_and_linker/unsorted/IroTransform.c +++ b/compiler_and_linker/unsorted/IroTransform.c @@ -1,3 +1,2794 @@ #include "compiler/IroTransform.h" +#include "compiler/CError.h" +#include "compiler/CFunc.h" +#include "compiler/CInt64.h" +#include "compiler/CIRTransform.h" +#include "compiler/CMachine.h" +#include "compiler/CPrep.h" +#include "compiler/CompilerTools.h" +#include "compiler/IroDump.h" +#include "compiler/IroLinearForm.h" +#include "compiler/IroMalloc.h" +#include "compiler/IroPointerAnalysis.h" +#include "compiler/IROUseDef.h" +#include "compiler/IroUtil.h" +#include "compiler/IroVars.h" +#include "compiler/enode.h" +#include "compiler/types.h" -// TODO +ENodeType ExprType; +ENode *IndirectRef; +Boolean FirstTime; +CInt64 OperandConst; +Object *OperandObject; +ENodeList *FirstAddend; +ENodeList *LastAddend; +static ENodeType AssignmentOp[MAXEXPR]; +static ENodeType ComplementaryOpLogical[MAXEXPR]; +static ENodeType ComplementaryOp[MAXEXPR]; + +// forward decls +static void DoDiadic(IROLinear *nd); + +static int GetTypeSize(Type *type) { + if (type->size == 1) + return 0; + if (type->size == 2) + return 1; + if (type->size == 4) + return 2; + if (type->size == 8) + return 3; + return -1; +} + +void IRO_InitializeAssignmentOpArray(void) { + int i; + + for (i = 0; i < MAXEXPR; i++) + AssignmentOp[i] = MAXEXPR; + + AssignmentOp[EPOSTINC] = MAXEXPR; + AssignmentOp[EPOSTDEC] = MAXEXPR; + AssignmentOp[EPREINC] = MAXEXPR; + AssignmentOp[EPREDEC] = MAXEXPR; + AssignmentOp[EINDIRECT] = MAXEXPR; + AssignmentOp[EMONMIN] = MAXEXPR; + AssignmentOp[EBINNOT] = MAXEXPR; + AssignmentOp[ELOGNOT] = MAXEXPR; + AssignmentOp[EFORCELOAD] = MAXEXPR; + AssignmentOp[EMUL] = EMULASS; + AssignmentOp[EMULV] = MAXEXPR; + AssignmentOp[EDIV] = EDIVASS; + AssignmentOp[EMODULO] = EMODASS; + AssignmentOp[EADDV] = MAXEXPR; + AssignmentOp[ESUBV] = MAXEXPR; + AssignmentOp[EADD] = EADDASS; + AssignmentOp[ESUB] = ESUBASS; + AssignmentOp[ESHL] = ESHLASS; + AssignmentOp[ESHR] = ESHRASS; + AssignmentOp[ELESS] = MAXEXPR; + AssignmentOp[EGREATER] = MAXEXPR; + AssignmentOp[ELESSEQU] = MAXEXPR; + AssignmentOp[EGREATEREQU] = MAXEXPR; + AssignmentOp[EEQU] = MAXEXPR; + AssignmentOp[ENOTEQU] = MAXEXPR; + AssignmentOp[EAND] = EANDASS; + AssignmentOp[EXOR] = EXORASS; + AssignmentOp[EOR] = EORASS; + AssignmentOp[ELAND] = MAXEXPR; + AssignmentOp[ELOR] = MAXEXPR; + AssignmentOp[EASS] = MAXEXPR; + AssignmentOp[EMULASS] = MAXEXPR; + AssignmentOp[EDIVASS] = MAXEXPR; + AssignmentOp[EMODASS] = MAXEXPR; + AssignmentOp[EADDASS] = MAXEXPR; + AssignmentOp[ESUBASS] = MAXEXPR; + AssignmentOp[ESHLASS] = MAXEXPR; + AssignmentOp[ESHRASS] = MAXEXPR; + AssignmentOp[EANDASS] = MAXEXPR; + AssignmentOp[EXORASS] = MAXEXPR; + AssignmentOp[EORASS] = MAXEXPR; + AssignmentOp[ECOMMA] = MAXEXPR; + AssignmentOp[EPMODULO] = MAXEXPR; + AssignmentOp[EROTL] = MAXEXPR; + AssignmentOp[EROTR] = MAXEXPR; + AssignmentOp[EBCLR] = MAXEXPR; + AssignmentOp[EBTST] = MAXEXPR; + AssignmentOp[EBSET] = MAXEXPR; + AssignmentOp[ETYPCON] = MAXEXPR; + AssignmentOp[EBITFIELD] = MAXEXPR; + AssignmentOp[EINTCONST] = MAXEXPR; + AssignmentOp[EFLOATCONST] = MAXEXPR; + AssignmentOp[ESTRINGCONST] = MAXEXPR; + AssignmentOp[ECOND] = MAXEXPR; + AssignmentOp[EFUNCCALL] = MAXEXPR; + AssignmentOp[EFUNCCALLP] = MAXEXPR; + AssignmentOp[EOBJREF] = MAXEXPR; + AssignmentOp[EMFPOINTER] = MAXEXPR; + AssignmentOp[ENULLCHECK] = MAXEXPR; + AssignmentOp[EPRECOMP] = MAXEXPR; + AssignmentOp[ETEMP] = MAXEXPR; + AssignmentOp[EARGOBJ] = MAXEXPR; + AssignmentOp[ELOCOBJ] = MAXEXPR; + AssignmentOp[ELABEL] = MAXEXPR; + AssignmentOp[ESETCONST] = MAXEXPR; + AssignmentOp[ENEWEXCEPTION] = MAXEXPR; + AssignmentOp[ENEWEXCEPTIONARRAY] = MAXEXPR; + AssignmentOp[EOBJLIST] = MAXEXPR; + AssignmentOp[EMEMBER] = MAXEXPR; + AssignmentOp[ETEMPLDEP] = MAXEXPR; + AssignmentOp[EINSTRUCTION] = MAXEXPR; + AssignmentOp[EDEFINE] = MAXEXPR; + AssignmentOp[EREUSE] = MAXEXPR; + AssignmentOp[EASSBLK] = MAXEXPR; + AssignmentOp[EVECTOR128CONST] = MAXEXPR; + AssignmentOp[ECONDASS] = MAXEXPR; +} + +void IRO_InitializeComplementaryOpArray(void) { + int i; + + for (i = 0; i < MAXEXPR; i++) + ComplementaryOp[i] = MAXEXPR; + + ComplementaryOp[EPOSTINC] = EPOSTDEC; + ComplementaryOp[EPOSTDEC] = EPOSTINC; + ComplementaryOp[EPREINC] = EPREDEC; + ComplementaryOp[EPREDEC] = EPREINC; + ComplementaryOp[EINDIRECT] = MAXEXPR; + ComplementaryOp[EMONMIN] = EMONMIN; + ComplementaryOp[EBINNOT] = EBINNOT; + ComplementaryOp[ELOGNOT] = ELOGNOT; + ComplementaryOp[EFORCELOAD] = MAXEXPR; + ComplementaryOp[EMUL] = EDIV; + ComplementaryOp[EMULV] = MAXEXPR; + ComplementaryOp[EDIV] = EMUL; + ComplementaryOp[EMODULO] = MAXEXPR; + ComplementaryOp[EADDV] = ESUBV; + ComplementaryOp[ESUBV] = EADDV; + ComplementaryOp[EADD] = ESUB; + ComplementaryOp[ESUB] = EADD; + ComplementaryOp[ESHL] = ESHR; + ComplementaryOp[ESHR] = ESHL; + ComplementaryOp[ELESS] = EGREATER; + ComplementaryOp[EGREATER] = ELESS; + ComplementaryOp[ELESSEQU] = EGREATEREQU; + ComplementaryOp[EGREATEREQU] = ELESSEQU; + ComplementaryOp[EEQU] = ENOTEQU; + ComplementaryOp[ENOTEQU] = EEQU; + ComplementaryOp[EAND] = EOR; + ComplementaryOp[EXOR] = MAXEXPR; + ComplementaryOp[EOR] = EAND; + ComplementaryOp[ELAND] = ELOR; + ComplementaryOp[ELOR] = ELAND; + ComplementaryOp[EASS] = MAXEXPR; + ComplementaryOp[EMULASS] = EDIVASS; + ComplementaryOp[EDIVASS] = EMULASS; + ComplementaryOp[EMODASS] = MAXEXPR; + ComplementaryOp[EADDASS] = ESUBASS; + ComplementaryOp[ESUBASS] = EADDASS; + ComplementaryOp[ESHLASS] = ESHRASS; + ComplementaryOp[ESHRASS] = ESHLASS; + ComplementaryOp[EANDASS] = EORASS; + ComplementaryOp[EXORASS] = MAXEXPR; + ComplementaryOp[EORASS] = EANDASS; + ComplementaryOp[ECOMMA] = MAXEXPR; + ComplementaryOp[EPMODULO] = MAXEXPR; + ComplementaryOp[EROTL] = EROTR; + ComplementaryOp[EROTR] = EROTL; + ComplementaryOp[EBCLR] = MAXEXPR; + ComplementaryOp[EBTST] = MAXEXPR; + ComplementaryOp[EBSET] = MAXEXPR; + ComplementaryOp[ETYPCON] = MAXEXPR; + ComplementaryOp[EBITFIELD] = MAXEXPR; + ComplementaryOp[EINTCONST] = MAXEXPR; + ComplementaryOp[EFLOATCONST] = MAXEXPR; + ComplementaryOp[ESTRINGCONST] = MAXEXPR; + ComplementaryOp[ECOND] = MAXEXPR; + ComplementaryOp[EFUNCCALL] = MAXEXPR; + ComplementaryOp[EFUNCCALLP] = MAXEXPR; + ComplementaryOp[EOBJREF] = MAXEXPR; + ComplementaryOp[EMFPOINTER] = MAXEXPR; + ComplementaryOp[ENULLCHECK] = MAXEXPR; + ComplementaryOp[EPRECOMP] = MAXEXPR; + ComplementaryOp[ETEMP] = MAXEXPR; + ComplementaryOp[EARGOBJ] = MAXEXPR; + ComplementaryOp[ELOCOBJ] = MAXEXPR; + ComplementaryOp[ELABEL] = MAXEXPR; + ComplementaryOp[ESETCONST] = MAXEXPR; + ComplementaryOp[ENEWEXCEPTION] = MAXEXPR; + ComplementaryOp[ENEWEXCEPTIONARRAY] = MAXEXPR; + ComplementaryOp[EOBJLIST] = MAXEXPR; + ComplementaryOp[EMEMBER] = MAXEXPR; + ComplementaryOp[ETEMPLDEP] = MAXEXPR; + ComplementaryOp[EINSTRUCTION] = MAXEXPR; + ComplementaryOp[EDEFINE] = MAXEXPR; + ComplementaryOp[EREUSE] = MAXEXPR; + ComplementaryOp[EASSBLK] = MAXEXPR; + ComplementaryOp[EVECTOR128CONST] = MAXEXPR; + ComplementaryOp[ECONDASS] = MAXEXPR; +} + +void IRO_InitializeComplementaryOpLogicalArray(void) { + int i; + + for (i = 0; i < MAXEXPR; i++) + ComplementaryOpLogical[i] = MAXEXPR; + + ComplementaryOpLogical[EPOSTINC] = MAXEXPR; + ComplementaryOpLogical[EPOSTDEC] = MAXEXPR; + ComplementaryOpLogical[EPREINC] = MAXEXPR; + ComplementaryOpLogical[EPREDEC] = MAXEXPR; + ComplementaryOpLogical[EINDIRECT] = MAXEXPR; + ComplementaryOpLogical[EMONMIN] = MAXEXPR; + ComplementaryOpLogical[EBINNOT] = MAXEXPR; + ComplementaryOpLogical[ELOGNOT] = ELOGNOT; + ComplementaryOpLogical[EFORCELOAD] = MAXEXPR; + ComplementaryOpLogical[EMUL] = MAXEXPR; + ComplementaryOpLogical[EMULV] = MAXEXPR; + ComplementaryOpLogical[EDIV] = MAXEXPR; + ComplementaryOpLogical[EMODULO] = MAXEXPR; + ComplementaryOpLogical[EADDV] = MAXEXPR; + ComplementaryOpLogical[ESUBV] = MAXEXPR; + ComplementaryOpLogical[EADD] = MAXEXPR; + ComplementaryOpLogical[ESUB] = MAXEXPR; + ComplementaryOpLogical[ESHL] = MAXEXPR; + ComplementaryOpLogical[ESHR] = MAXEXPR; + ComplementaryOpLogical[ELESS] = EGREATEREQU; + ComplementaryOpLogical[EGREATER] = ELESSEQU; + ComplementaryOpLogical[ELESSEQU] = EGREATER; + ComplementaryOpLogical[EGREATEREQU] = ELESS; + ComplementaryOpLogical[EEQU] = ENOTEQU; + ComplementaryOpLogical[ENOTEQU] = EEQU; + ComplementaryOpLogical[EAND] = MAXEXPR; + ComplementaryOpLogical[EXOR] = MAXEXPR; + ComplementaryOpLogical[EOR] = MAXEXPR; + ComplementaryOpLogical[ELAND] = ELOR; + ComplementaryOpLogical[ELOR] = ELAND; + ComplementaryOpLogical[EASS] = MAXEXPR; + ComplementaryOpLogical[EMULASS] = MAXEXPR; + ComplementaryOpLogical[EDIVASS] = MAXEXPR; + ComplementaryOpLogical[EMODASS] = MAXEXPR; + ComplementaryOpLogical[EADDASS] = MAXEXPR; + ComplementaryOpLogical[ESUBASS] = MAXEXPR; + ComplementaryOpLogical[ESHLASS] = MAXEXPR; + ComplementaryOpLogical[ESHRASS] = MAXEXPR; + ComplementaryOpLogical[EANDASS] = MAXEXPR; + ComplementaryOpLogical[EXORASS] = MAXEXPR; + ComplementaryOpLogical[EORASS] = MAXEXPR; + ComplementaryOpLogical[ECOMMA] = MAXEXPR; + ComplementaryOpLogical[EPMODULO] = MAXEXPR; + ComplementaryOpLogical[EROTL] = MAXEXPR; + ComplementaryOpLogical[EROTR] = MAXEXPR; + ComplementaryOpLogical[EBCLR] = MAXEXPR; + ComplementaryOpLogical[EBTST] = MAXEXPR; + ComplementaryOpLogical[EBSET] = MAXEXPR; + ComplementaryOpLogical[ETYPCON] = MAXEXPR; + ComplementaryOpLogical[EBITFIELD] = MAXEXPR; + ComplementaryOpLogical[EINTCONST] = MAXEXPR; + ComplementaryOpLogical[EFLOATCONST] = MAXEXPR; + ComplementaryOpLogical[ESTRINGCONST] = MAXEXPR; + ComplementaryOpLogical[ECOND] = MAXEXPR; + ComplementaryOpLogical[EFUNCCALL] = MAXEXPR; + ComplementaryOpLogical[EFUNCCALLP] = MAXEXPR; + ComplementaryOpLogical[EOBJREF] = MAXEXPR; + ComplementaryOpLogical[EMFPOINTER] = MAXEXPR; + ComplementaryOpLogical[ENULLCHECK] = MAXEXPR; + ComplementaryOpLogical[EPRECOMP] = MAXEXPR; + ComplementaryOpLogical[ETEMP] = MAXEXPR; + ComplementaryOpLogical[EARGOBJ] = MAXEXPR; + ComplementaryOpLogical[ELOCOBJ] = MAXEXPR; + ComplementaryOpLogical[ELABEL] = MAXEXPR; + ComplementaryOpLogical[ESETCONST] = MAXEXPR; + ComplementaryOpLogical[ENEWEXCEPTION] = MAXEXPR; + ComplementaryOpLogical[ENEWEXCEPTIONARRAY] = MAXEXPR; + ComplementaryOpLogical[EOBJLIST] = MAXEXPR; + ComplementaryOpLogical[EMEMBER] = MAXEXPR; + ComplementaryOpLogical[ETEMPLDEP] = MAXEXPR; + ComplementaryOpLogical[EINSTRUCTION] = MAXEXPR; + ComplementaryOpLogical[EDEFINE] = MAXEXPR; + ComplementaryOpLogical[EREUSE] = MAXEXPR; + ComplementaryOpLogical[EASSBLK] = MAXEXPR; + ComplementaryOpLogical[EVECTOR128CONST] = MAXEXPR; + ComplementaryOpLogical[ECONDASS] = MAXEXPR; +} + +static void DoTransformations(IROLinear *nd) { + IROLinear *nd2; + IROLinear *nd3; + IROLinear *nd4; + IROLinear *nd5; + Type *newtype; + SInt32 value; + + if (nd->type == IROLinearOp2Arg) { + switch (nd->nodetype) { + case EASS: + nd2 = nd->u.diadic.right; + if ( + nd2->type == IROLinearOp2Arg && + AssignmentOp[nd2->nodetype] < MAXEXPR && + IRO_TypesEqual(nd->rtype, nd2->rtype) && + IRO_IsVariable(nd3 = nd->u.diadic.left) && + !(nd3->flags & IROLF_BitfieldIndirect) && + IRO_ExprsSame(nd3, nd2->u.diadic.left) + ) + { + nd->nodetype = AssignmentOp[nd2->nodetype]; + nd->u.diadic.right = nd2->u.diadic.right; + IRO_NopOut(nd2->u.diadic.left); + nd2->type = IROLinearNop; + + nd3->flags |= IROLF_Used; + nd3->u.diadic.left->flags |= IROLF_Used; + } + break; + + case EMUL: + if ( + IS_TYPE_INT(nd->rtype) && + IRO_IsPow2(nd->u.diadic.right, &value) + ) + { + nd->nodetype = ESHL; + CInt64_SetLong(&nd->u.diadic.right->u.node->data.intval, value); + } + break; + + case EDIV: + if ( + IS_TYPE_INT(nd->rtype) && + IRO_IsPow2(nd->u.diadic.right, &value) + ) + { + if (IRO_IsUnsignedType(nd->rtype)) { + nd->nodetype = ESHR; + CInt64_SetLong(&nd->u.diadic.right->u.node->data.intval, value); + } else if ( + !IRO_IsUnsignedType(nd->rtype) && + TYPE_INTEGRAL(nd->rtype)->integral != IT_BOOL && + nd->u.diadic.left->nodetype == ETYPCON && + IS_TYPE_INT(nd->u.diadic.left->u.monadic->rtype) && + IRO_IsUnsignedType(nd->u.diadic.left->u.monadic->rtype) && + nd->u.diadic.left->u.monadic->rtype->size < nd->u.diadic.left->rtype->size + ) + { + nd->nodetype = ESHR; + CInt64_SetLong(&nd->u.diadic.right->u.node->data.intval, value); + if (nd->flags & IROLF_Reffed) { + IROLinear *copy = IRO_NewLinear(IROLinearOp1Arg); + memcpy(copy, nd, sizeof(IROLinear)); + copy->type = IROLinearOp1Arg; + copy->nodetype = ETYPCON; + copy->index = IRO_NumLinear++; + copy->rtype = nd->rtype; + IRO_PasteAfter(copy, copy, nd); + IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, copy); + copy->u.monadic = nd; + nd->flags |= IROLF_Reffed; + } + nd->rtype = IRO_UnsignedType(nd->rtype); + newtype = IRO_UnsignedType(nd->u.diadic.right->rtype); + nd->u.diadic.right->u.node->rtype = newtype; + nd->u.diadic.right->rtype = newtype; + nd->u.diadic.left->rtype = IRO_UnsignedType(nd->u.diadic.left->rtype); + } + } + break; + + case EMODULO: + if ( + IS_TYPE_INT(nd->rtype) && + IRO_IsUnsignedType(nd->rtype) && + IRO_IsPow2(nd->u.diadic.right, &value) + ) + { + nd->nodetype = EAND; + nd->u.diadic.right->u.node->data.intval = CInt64_Sub(nd->u.diadic.right->u.node->data.intval, cint64_one); + } + break; + + case EEQU: + if ( + (nd2 = IRO_LocateFather(nd)) && + nd2->nodetype == ETYPCON && + IS_TYPE_INT(nd2->rtype) && + (nd3 = IRO_LocateFather(nd2)) && + nd3->nodetype == ELOGNOT && + (nd4 = IRO_LocateFather(nd3)) && + nd4->nodetype == ETYPCON && + IS_TYPE_INT(nd4->rtype) && + ( + ((nd5 = IRO_LocateFather(nd4)) && nd5->type == IROLinearIf) || + nd5->type == IROLinearIfNot + ) + ) + { + IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd4, nd); + nd->nodetype = ENOTEQU; + nd2->type = IROLinearNop; + nd3->type = IROLinearNop; + nd4->type = IROLinearNop; + } + break; + } + } +} + +static void IRO_SwitchChildren(IROLinear *nd) { + IROLinear *tmp = nd->u.diadic.left; + nd->u.diadic.left = nd->u.diadic.right; + nd->u.diadic.right = tmp; +} + +static void ReplaceExprWithConst(IROLinear *nd, CInt64 val) { + IRO_NopOut(nd); + nd->type = IROLinearOperand; + nd->nodetype = EINTCONST; + nd->u.node = IRO_NewENode(EINTCONST); + nd->u.node->data.intval = val; + nd->u.node->flags = nd->nodeflags; + nd->u.node->rtype = nd->rtype; + + if (IS_TYPE_FLOAT(nd->rtype)) { + nd->u.node->type = EFLOATCONST; + nd->nodetype = EFLOATCONST; + nd->u.node->data.floatval = CMach_CalcFloatConvertFromInt(TYPE(&stsignedlong), val); + } +} + +static void ReplaceExprWithLeftChild(IROLinear *nd) { + IROLinear *left = nd->u.diadic.left; + IROLinear *right = nd->u.diadic.right; + + if (left->rtype == nd->rtype) { + IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, left); + left->flags = nd->flags; + left->nodeflags = nd->nodeflags; + nd->type = IROLinearNop; + IRO_NopOut(right); + } else { + nd->type = IROLinearOp1Arg; + nd->nodetype = ETYPCON; + nd->u.monadic = left; + IRO_NopOut(right); + } +} + +static void ReplaceExprWithRightChild(IROLinear *nd) { + IROLinear *left = nd->u.diadic.left; + IROLinear *right = nd->u.diadic.right; + + if (right->rtype == nd->rtype) { + IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, right); + right->flags = nd->flags; + right->nodeflags = nd->nodeflags; + nd->type = IROLinearNop; + IRO_NopOut(left); + } else { + nd->type = IROLinearOp1Arg; + nd->nodetype = ETYPCON; + nd->u.monadic = right; + IRO_NopOut(left); + } +} + +static void ReplaceExprWithMonaminRight(IROLinear *nd) { + IROLinear *left = nd->u.diadic.left; + IROLinear *right = nd->u.diadic.right; + + if (right->rtype == nd->rtype) { + nd->type = IROLinearOp1Arg; + nd->nodetype = EMONMIN; + nd->u.monadic = right; + IRO_NopOut(left); + } else { + IRO_NopOut(left); + left->type = IROLinearOp1Arg; + left->nodetype = ETYPCON; + left->expr = right->expr; + left->rtype = nd->rtype; + left->u.monadic = right; + nd->type = IROLinearOp1Arg; + nd->nodetype = EMONMIN; + nd->u.monadic = left; + } +} + +static void ReplaceExprWithMonaminLeft(IROLinear *nd) { + IROLinear *left = nd->u.diadic.left; + IROLinear *right = nd->u.diadic.right; + + if (left->rtype == nd->rtype) { + nd->type = IROLinearOp1Arg; + nd->nodetype = EMONMIN; + nd->u.monadic = left; + IRO_NopOut(right); + } else { + IRO_NopOut(right); + right->type = IROLinearOp1Arg; + right->nodetype = ETYPCON; + right->expr = left->expr; + right->rtype = nd->rtype; + right->u.monadic = left; + nd->type = IROLinearOp1Arg; + nd->nodetype = EMONMIN; + nd->u.monadic = right; + } +} + +static void switchFatherLeftMonadic(IROLinear *nd) { + IROLinear *inner = nd->u.monadic; + IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, inner); + nd->u.monadic = inner->u.monadic; + inner->u.monadic = nd; + inner->rtype = nd->rtype; + inner->flags = nd->flags; + inner->nodeflags = nd->nodeflags; + IRO_CutAndPasteAfter(inner, inner, nd); +} + +static void switchFatherLeft(IROLinear *nd, int isRight) { + IROLinear *a; + IROLinear *b; + + a = nd->u.diadic.left; + IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, a); + + if (isRight) { + nd->u.diadic.left = a->u.diadic.left; + a->u.diadic.left = nd; + b = a->u.diadic.right; + } else { + nd->u.diadic.left = a->u.diadic.right; + a->u.diadic.right = nd; + b = a->u.diadic.left; + } + + a->rtype = nd->rtype; + a->flags = nd->flags; + a->nodeflags = nd->nodeflags; + IRO_CutAndPasteAfter(a, a, nd); + IRO_CutAndPasteAfter(IRO_FindFirst(b), b, nd); +} + +static void PickCommonsubAtLeftLeft(IROLinear *nd) { + switchFatherLeft(nd, 0); + ReplaceExprWithRightChild(nd->u.diadic.right); +} + +static void PickCommonsubAtRightLeft(IROLinear *nd) { + switchFatherLeft(nd, 1); + ReplaceExprWithRightChild(nd->u.diadic.right); +} + +static void PickCommonsubAtLeftRight(IROLinear *nd) { + switchFatherLeft(nd, 0); + ReplaceExprWithLeftChild(nd->u.diadic.right); +} + +static void PickCommonsubAtRightRight(IROLinear *nd) { + switchFatherLeft(nd, 1); + ReplaceExprWithLeftChild(nd->u.diadic.right); +} + +static void DoTransformations11(IROLinear *nd) { + IROLinear *left; + IROLinear *right; + int changed; + int compare; + Type *type; + SInt32 tmp1; + SInt32 tmp2; + CInt64 val; + + if (nd->type == IROLinearOp2Arg) { + left = nd->u.diadic.left; + right = nd->u.diadic.right; + if (IS_TYPE_FLOAT(nd->rtype) || IS_TYPE_FLOAT(left->rtype) || IS_TYPE_FLOAT(right->rtype)) + return; + + changed = 0; + if (!IRO_HasSideEffect(left) && !IRO_HasSideEffect(right)) { + if (IRO_IsIntConstant(right) || IRO_IsFloatConstant(right)) { + if (IRO_IsConstantZero(right)) { + switch (nd->nodetype) { + case EADDV: + case ESUBV: + case EADD: + case ESUB: + case ESHL: + case ESHR: + case EXOR: + case EOR: + case ELOR: + case EADDASS: + case ESUBASS: + case ESHLASS: + case ESHRASS: + case EXORASS: + case EORASS: + ReplaceExprWithLeftChild(nd); + changed = 1; + break; + case EMUL: + case EAND: + case ELAND: + ReplaceExprWithConst(nd, cint64_zero); + changed = 1; + break; + case EMULASS: + case EANDASS: + nd->nodetype = EASS; + nd->u.diadic.right->rtype = nd->rtype; + nd->u.diadic.right->u.node->rtype = nd->rtype; + changed = 1; + break; + case EDIV: + case EMODULO: + case EDIVASS: + case EMODASS: + if (nd->stmt->sourceoffset) { + TStreamElement *token = CPrep_CurStreamElement(); + token->tokenoffset = nd->stmt->sourceoffset; + CError_SetErrorToken(token); + } + CError_Warning(CErrorStr139); + break; + } + } else if (nd->nodetype == ELAND) { + ReplaceExprWithLeftChild(nd); + changed = 1; + } else if (nd->nodetype == ELOR) { + ReplaceExprWithConst(nd, cint64_one); + changed = 1; + } else if (nd->nodetype == ESHL || nd->nodetype == ESHR || nd->nodetype == ESHLASS || nd->nodetype == ESHRASS) { + type = nd->rtype; + tmp1 = type->size * 8; + if (left->type == IROLinearOp1Arg && left->nodetype == ETYPCON) { + type = left->u.monadic->rtype; + if ( + left->u.monadic->type == IROLinearOp1Arg && + left->u.monadic->nodetype == EINDIRECT && + left->u.monadic->u.monadic->type == IROLinearOp1Arg && + left->u.monadic->u.monadic->nodetype == EBITFIELD && + IS_TYPE_BITFIELD(left->u.monadic->u.monadic->rtype) + ) + tmp2 = TYPE_BITFIELD(left->u.monadic->u.monadic->rtype)->unkB; + else + tmp2 = type->size * 8; + } else { + tmp2 = tmp1; + } + + switch (nd->nodetype) { + case ESHL: + case ESHLASS: + CInt64_SetLong(&val, tmp1); + if (IRO_IsUnsignedType(type)) + compare = CInt64_GreaterEqualU(right->u.node->data.intval, val); + else + compare = CInt64_GreaterEqual(right->u.node->data.intval, val); + break; + case ESHR: + case ESHRASS: + CInt64_SetLong(&val, tmp2); + compare = IRO_IsUnsignedType(type) && CInt64_GreaterEqualU(right->u.node->data.intval, val); + break; + } + + if (compare) { + switch (nd->nodetype) { + case ESHL: + case ESHR: + ReplaceExprWithConst(nd, cint64_zero); + break; + case ESHLASS: + case ESHRASS: + nd->nodetype = EASS; + ReplaceExprWithConst(right, cint64_zero); + break; + } + changed = 1; + } + } else if (IRO_IsConstantOne(right)) { + switch (nd->nodetype) { + case EMUL: + case EMULV: + case EDIV: + case EMULASS: + case EDIVASS: + ReplaceExprWithLeftChild(nd); + changed = 1; + break; + case EMODULO: + ReplaceExprWithConst(nd, cint64_zero); + changed = 1; + break; + case EMODASS: + nd->nodetype = EASS; + ReplaceExprWithConst(right, cint64_zero); + nd->u.diadic.right->rtype = nd->rtype; + nd->u.diadic.right->u.node->rtype = nd->rtype; + changed = 1; + break; + } + } else if (IRO_IsConstantNegativeOne(right)) { + switch (nd->nodetype) { + case EMUL: + case EMULV: + case EDIV: + ReplaceExprWithMonaminLeft(nd); + changed = 1; + break; + case EMODULO: + ReplaceExprWithConst(nd, cint64_zero); + changed = 1; + break; + case EMODASS: + nd->nodetype = EASS; + ReplaceExprWithConst(right, cint64_zero); + nd->u.diadic.right->rtype = nd->rtype; + nd->u.diadic.right->u.node->rtype = nd->rtype; + changed = 1; + break; + } + } + } + + if (!changed && (IRO_IsIntConstant(left) || IRO_IsFloatConstant(left))) { + if (IRO_IsConstantZero(left)) { + switch (nd->nodetype) { + case EADDV: + case EADD: + case EXOR: + case EOR: + case ELOR: + ReplaceExprWithRightChild(nd); + break; + case EMUL: + case ESHL: + case ESHR: + case EAND: + case ELAND: + ReplaceExprWithConst(nd, cint64_zero); + break; + case ESUBV: + case ESUB: + ReplaceExprWithMonaminRight(nd); + break; + } + } else if (nd->nodetype == ELAND) { + ReplaceExprWithRightChild(nd); + } else if (nd->nodetype == ELOR) { + ReplaceExprWithConst(nd, cint64_one); + } else if (IRO_IsConstantOne(left)) { + switch (nd->nodetype) { + case EMUL: + case EMULV: + ReplaceExprWithRightChild(nd); + break; + } + } else if (IRO_IsConstantNegativeOne(left)) { + switch (nd->nodetype) { + case EMUL: + case EMULV: + ReplaceExprWithMonaminRight(nd); + break; + } + } + } + } + } +} + +static void DoTransformations12(IROLinear *nd) { + IROLinear *left; + IROLinear *right; + + if (nd->type == IROLinearOp2Arg) { + left = nd->u.diadic.left; + right = nd->u.diadic.right; + if (IS_TYPE_FLOAT(nd->rtype) || IS_TYPE_FLOAT(left->rtype) || IS_TYPE_FLOAT(right->rtype)) + return; + + if (IRO_ExprsSameSemantically(left, right) && !IRO_HasSideEffect(left)) { + switch (nd->nodetype) { + case ESUBV: + case ESUB: + case ELESS: + case EGREATER: + case ENOTEQU: + case EXOR: + ReplaceExprWithConst(nd, cint64_zero); + break; + case ELESSEQU: + case EGREATEREQU: + case EEQU: + ReplaceExprWithConst(nd, cint64_one); + break; + case EAND: + case EOR: + case ELAND: + case ELOR: + case EASS: + case EANDASS: + case EORASS: + ReplaceExprWithLeftChild(nd); + break; + case ESUBASS: + case EXORASS: + nd->nodetype = EASS; + ReplaceExprWithConst(right, cint64_zero); + break; + } + } + } +} + +static void DoTransformations13(IROLinear *nd) { + IROLinear *left; + IROLinear *right; + IROLinear *left2; + IROLinear *right2; + IROListNode *tmp; + IROListNode *leftlist; + IROListNode *rightlist; + + if (nd->type == IROLinearOp2Arg) { + left = nd->u.diadic.left; + right = nd->u.diadic.right; + + if ( + !IRO_HasSideEffect(left) && + !IRO_HasSideEffect(right) && + (nd->nodetype == EEQU || nd->nodetype == ENOTEQU) && + PointerAnalysis_IsLinearNodePointerExprDefinite(FunctionName, left) && + PointerAnalysis_IsLinearNodePointerExprDefinite(FunctionName, right) + ) + { + leftlist = NULL; + PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, left, &leftlist); + if (leftlist) { + if (leftlist->list.head && leftlist->list.tail && !leftlist->nextList) { + rightlist = NULL; + PointerAnalysis_LookupLinearNodePointerExpr(FunctionName, right, &rightlist); + if (rightlist) { + if (rightlist->list.head && rightlist->list.tail && !rightlist->nextList) { + left2 = leftlist->list.tail; + right2 = rightlist->list.tail; + if (IRO_ExprsSameSemantically(left2, right2)) { + ReplaceExprWithConst(nd, (nd->nodetype == EEQU) ? cint64_one : cint64_zero); + } else if (left2->type == right2->type && IRO_TypesEqual(left2->rtype, right2->rtype)) { + ReplaceExprWithConst(nd, (nd->nodetype == EEQU) ? cint64_zero : cint64_one); + } + } + + while (rightlist) { + tmp = rightlist->nextList; + IRO_free(rightlist); + rightlist = tmp; + } + } + } + + while (leftlist) { + tmp = leftlist->nextList; + IRO_free(leftlist); + leftlist = tmp; + } + } + } + } +} + +static void DoTransformations21(IROLinear *nd) { + IROLinear *left; + IROLinear *right; + Boolean changed; + + if (nd->type == IROLinearOp2Arg) { + left = nd->u.diadic.left; + right = nd->u.diadic.right; + + if (left->type == IROLinearOp1Arg && right->type == IROLinearOp1Arg && left->nodetype == right->nodetype) { + switch (left->nodetype) { + case EMONMIN: + case EBINNOT: + case ELOGNOT: + changed = 0; + switch (nd->nodetype) { + case EXOR: + if (left->nodetype == EBINNOT) + goto collapse; + break; + case ELESS: + case EGREATER: + case ELESSEQU: + case EGREATEREQU: + if (left->nodetype == EMONMIN) { + nd->nodetype = ComplementaryOp[nd->nodetype]; + goto collapse; + } + break; + case EMUL: + case EDIV: + if (left->nodetype == EMONMIN) + goto collapse; + break; + case EEQU: + case ENOTEQU: + if (left->nodetype != ELOGNOT) { + collapse: + nd->u.diadic.left = left->u.monadic; + nd->u.diadic.right = right->u.monadic; + left->type = right->type = IROLinearNop; + changed = 1; + } + break; + case ELAND: + case ELOR: + if (left->nodetype == ELOGNOT) { + nd->nodetype = ComplementaryOp[nd->nodetype]; + goto switchfather; + } + break; + case EAND: + case EOR: + if ( + !IS_TYPE_FLOAT(nd->rtype) && + !IS_TYPE_FLOAT(left->rtype) && + !IS_TYPE_FLOAT(right->rtype) && + left->nodetype != EMONMIN + ) + { + nd->nodetype = ComplementaryOp[nd->nodetype]; + goto switchfather; + } + break; + case EADD: + case ESUB: + if ( + !IS_TYPE_FLOAT(nd->rtype) && + !IS_TYPE_FLOAT(left->rtype) && + !IS_TYPE_FLOAT(right->rtype) && + left->nodetype == EMONMIN + ) + { + switchfather: + switchFatherLeftMonadic(nd); + nd->u.diadic.right = right->u.monadic; + right->type = IROLinearNop; + changed = 1; + } + break; + } + + if (changed) { + DoTransformations(nd); + DoTransformations11(nd); + DoTransformations12(nd); + DoTransformations13(nd); + } + break; + } + } + } +} + +static void DoTransformations22(IROLinear *nd) { + IROLinear *left; + IROLinear *right; + IROLinear *ndtmp; + + if (nd->type == IROLinearOp2Arg) { + left = nd->u.diadic.left; + right = nd->u.diadic.right; + if (IS_TYPE_FLOAT(nd->rtype) || IS_TYPE_FLOAT(left->rtype) || IS_TYPE_FLOAT(right->rtype)) + return; + + if (!IRO_HasSideEffect(left) && !IRO_HasSideEffect(right)) { + if (left->type == IROLinearOp1Arg && left->nodetype == EMONMIN) { + switch (nd->nodetype) { + case ESUB: + case ESUBV: + nd->nodetype = ComplementaryOp[nd->nodetype]; + switchFatherLeftMonadic(nd); + break; + + case EADD: + case EADDV: + nd->nodetype = ComplementaryOp[nd->nodetype]; + nd->u.diadic.left = right; + nd->u.diadic.right = left->u.monadic; + left->type = IROLinearNop; + DoTransformations(nd); + DoTransformations12(nd); + DoTransformations21(nd); + break; + + case EDIV: + if (IRO_ExprsSameSemantically(left->u.monadic, right)) + ReplaceExprWithConst(nd, cint64_negone); + break; + } + } else { + ndtmp = NULL; + if (left->type == IROLinearOp1Arg && IRO_ExprsSameSemantically(left->u.monadic, right)) + ndtmp = left; + else if (right->type == IROLinearOp1Arg && IRO_ExprsSameSemantically(left, right->u.monadic)) + ndtmp = right; + + if (ndtmp) { + switch (nd->nodetype) { + case EAND: + if (ndtmp->nodetype == EBINNOT || ndtmp->nodetype == ELOGNOT) + ReplaceExprWithConst(nd, cint64_zero); + break; + + case EANDASS: + if (ndtmp->nodetype == EBINNOT || ndtmp->nodetype == ELOGNOT) { + nd->nodetype = EASS; + ReplaceExprWithConst(right, cint64_zero); + nd->u.diadic.right->rtype = nd->rtype; + nd->u.diadic.right->u.node->rtype = nd->rtype; + } + break; + + case EXOR: + case EOR: + if (ndtmp->nodetype == EBINNOT) { + ReplaceExprWithConst(nd, cint64_zero); + nd->u.node->data.intval = CInt64_Inv(nd->u.node->data.intval); + } + break; + + case EXORASS: + case EORASS: + if (ndtmp->nodetype == EBINNOT) { + nd->nodetype = EASS; + ReplaceExprWithConst(right, cint64_zero); + right->u.node->data.intval = CInt64_Inv(right->u.node->data.intval); + nd->u.diadic.right->rtype = nd->rtype; + nd->u.diadic.right->u.node->rtype = nd->rtype; + } + break; + + case ELOR: + if (ndtmp->nodetype == EBINNOT || ndtmp->nodetype == ELOGNOT) + ReplaceExprWithConst(nd, cint64_one); + break; + + case ELAND: + if (ndtmp->nodetype == ELOGNOT) + ReplaceExprWithConst(nd, cint64_zero); + break; + + case EDIV: + if (ndtmp->nodetype == EMONMIN) + ReplaceExprWithConst(nd, cint64_negone); + break; + + case EDIVASS: + if (ndtmp->nodetype == EMONMIN) { + nd->nodetype = EASS; + ReplaceExprWithConst(right, cint64_negone); + nd->u.diadic.right->rtype = nd->rtype; + nd->u.diadic.right->u.node->rtype = nd->rtype; + } + break; + } + } + } + } + } +} + +static void DoTransformations23(IROLinear *nd) { + Boolean changed; + Boolean isCompare; + UInt8 which; + IROLinear *left; + IROLinear *right; + CInt64 size; + CInt64 val; + + if (nd->type == IROLinearOp2Arg && !IRO_HasSideEffect(nd)) { + left = nd->u.diadic.left; + right = nd->u.diadic.right; + if (IS_TYPE_FLOAT(nd->rtype) || IS_TYPE_FLOAT(left->rtype) || IS_TYPE_FLOAT(right->rtype)) + return; + + isCompare = 0; + changed = 0; + which = 0; + + switch (nd->nodetype) { + case ELESS: + case EGREATER: + case ELESSEQU: + case EGREATEREQU: + isCompare = 1; + case EADDV: + case EADD: + case EEQU: + case ENOTEQU: + case EAND: + case EOR: + if (left->type == IROLinearOp2Arg) { + if (IRO_ExprsSameSemantically(right, left->u.diadic.left)) + which = 1; + else if (IRO_ExprsSameSemantically(right, left->u.diadic.right)) + which = 2; + + if (which) { + if (isCompare) + nd->nodetype = ComplementaryOp[nd->nodetype]; + IRO_SwitchChildren(nd); + left = nd->u.diadic.left; + right = nd->u.diadic.right; + break; + } + } + case ESUBV: + case ESUB: + case EADDASS: + case ESUBASS: + case EANDASS: + case EORASS: + if (right->type == IROLinearOp2Arg) { + if (IRO_ExprsSameSemantically(left, right->u.diadic.left)) + which = 1; + else if (IRO_ExprsSameSemantically(left, right->u.diadic.right)) + which = 2; + } + break; + + default: + goto done; + } + + if (which) { + switch (right->nodetype) { + case EAND: + case EOR: + if (which == 2) + IRO_SwitchChildren(right); + + if ( + nd->nodetype == right->nodetype || + (nd->nodetype == EANDASS && right->nodetype == EAND) || + (nd->nodetype == EORASS && right->nodetype == EOR) + ) + { + ReplaceExprWithRightChild(right); + changed = 1; + } + else if ( + nd->nodetype == ComplementaryOp[right->nodetype] || + (nd->nodetype == EANDASS && right->nodetype == EOR) || + (nd->nodetype == EORASS && right->nodetype == EAND) + ) + { + ReplaceExprWithLeftChild(nd); + } + break; + + case EADD: + if (which == 2) + IRO_SwitchChildren(right); + + switch (nd->nodetype) { + case EEQU: + case ENOTEQU: + ReplaceExprWithConst(left, cint64_zero); + ReplaceExprWithRightChild(right); + IRO_SwitchChildren(nd); + if (isCompare) + nd->nodetype = ComplementaryOp[nd->nodetype]; + changed = 1; + break; + + case ESUB: + case ESUBV: + ReplaceExprWithRightChild(right); + ReplaceExprWithMonaminRight(nd); + changed = 1; + break; + + case ESUBASS: + ReplaceExprWithRightChild(right); + changed = 1; + break; + } + break; + + case ESUB: + switch (nd->nodetype) { + case EEQU: + case ENOTEQU: + if (which == 1) { + ReplaceExprWithConst(left, cint64_zero); + ReplaceExprWithRightChild(right); + IRO_SwitchChildren(nd); + } + break; + case EADD: + case EADDV: + if (which == 2) { + ReplaceExprWithLeftChild(right); + ReplaceExprWithRightChild(nd); + } + break; + case ESUB: + case ESUBV: + if (which == 1) { + ReplaceExprWithRightChild(right); + ReplaceExprWithRightChild(nd); + } + break; + case EADDASS: + if (which == 2) { + nd->nodetype = EASS; + ReplaceExprWithLeftChild(right); + changed = 1; + } + break; + case ESUBASS: + if (which == 1) { + nd->nodetype = EASS; + ReplaceExprWithRightChild(right); + changed = 1; + } + break; + } + break; + } + } + + done: + if (!changed) { + switch (nd->nodetype) { + case ESUB: + case ESUBV: + which = 0; + if (left->type == IROLinearOp2Arg) { + if (IRO_ExprsSameSemantically(right, left->u.diadic.left)) + which = 1; + else if (IRO_ExprsSameSemantically(right, left->u.diadic.right)) + which = 2; + } + + if (which == 1) { + if (left->nodetype == ESUB) { + ReplaceExprWithMonaminRight(left); + ReplaceExprWithLeftChild(nd); + } else if (left->nodetype == EADD) { + ReplaceExprWithRightChild(left); + ReplaceExprWithLeftChild(nd); + } + } else if (which == 2) { + if (left->nodetype == EADD) { + ReplaceExprWithLeftChild(left); + ReplaceExprWithLeftChild(nd); + } + } + break; + } + + switch (nd->nodetype) { + case ESHL: + case ESHR: + case ESHLASS: + case ESHRASS: + which = 0; + if (left->type == IROLinearOp2Arg) { + if (left->nodetype == ComplementaryOp[nd->nodetype] || left->nodetype == AssignmentOp[ComplementaryOp[nd->nodetype]]) { + if (IRO_IsIntConstant(right) && IRO_ExprsSameSemantically(right, left->u.diadic.right)) + which = 2; + } + } + + if (which == 2) { + val = right->u.node->data.intval; + if (left->nodetype == ESHR || left->nodetype == ESHRASS) { + ReplaceExprWithLeftChild(left); + nd->nodetype = (nd->nodetype == ESHL) ? EAND : EANDASS; + right->u.node->data.intval = CInt64_Shl(cint64_negone, val); + changed = 1; + } else if (IRO_IsUnsignedType(nd->rtype)) { + ReplaceExprWithLeftChild(left); + nd->nodetype = (nd->nodetype == ESHR) ? EAND : EANDASS; + if (nd->rtype->size < 8) { + CInt64_SetLong(&size, 64 - 8 * nd->rtype->size); + val = CInt64_Add(val, size); + } + right->u.node->data.intval = CInt64_ShrU(cint64_negone, val); + changed = 1; + } + } + break; + } + } + + if (changed) { + DoTransformations(nd); + DoTransformations11(nd); + DoTransformations12(nd); + DoTransformations13(nd); + DoTransformations21(nd); + DoTransformations22(nd); + DoTransformations23(nd); + } + } +} + +static void DoTransformations24(IROLinear *nd) { + IROLinear *left; + IROLinear *right; + UInt8 changed; + + if (nd->type == IROLinearOp2Arg) { + left = nd->u.diadic.left; + right = nd->u.diadic.right; + if (IS_TYPE_FLOAT(nd->rtype) || IS_TYPE_FLOAT(left->rtype) || IS_TYPE_FLOAT(right->rtype)) + return; + + if (left->type == IROLinearOp2Arg && right->type == IROLinearOp2Arg && !IRO_HasSideEffect(nd)) { + changed = 0; + + if (IRO_ExprsSameSemantically(left->u.diadic.left, right->u.diadic.left)) { + if (left->nodetype == right->nodetype) { + switch (left->nodetype) { + case EADD: + if (nd->nodetype == ComplementaryOp[left->nodetype]) { + ReplaceExprWithRightChild(left); + ReplaceExprWithRightChild(right); + changed = 1; + } + break; + case ESUB: + if (nd->nodetype == ESUB || nd->nodetype == ESUBV) { + ReplaceExprWithRightChild(left); + ReplaceExprWithRightChild(right); + IRO_SwitchChildren(nd); + changed = 1; + } + break; + case EMUL: + switch (nd->nodetype) { + case EADD: + case ESUB: + PickCommonsubAtLeftLeft(nd); + changed = 3; + break; + } + break; + case EAND: + if (nd->nodetype == EXOR) { + PickCommonsubAtLeftLeft(nd); + changed = 3; + break; + } + case EOR: + if (nd->nodetype == left->nodetype) { + ReplaceExprWithRightChild(left); + changed = 1; + } else if (nd->nodetype == ComplementaryOp[left->nodetype]) { + PickCommonsubAtLeftLeft(nd); + changed = 3; + } + break; + } + } else if (left->nodetype == ComplementaryOp[right->nodetype]) { + switch (nd->nodetype) { + case ESUB: + case ESUBV: + switch (left->nodetype) { + case EADD: + nd->nodetype = ComplementaryOp[nd->nodetype]; + ReplaceExprWithRightChild(left); + ReplaceExprWithRightChild(right); + changed = 1; + break; + case ESUB: + ReplaceExprWithMonaminRight(left); + ReplaceExprWithRightChild(right); + changed = 1; + break; + } + break; + + case EAND: + case EOR: + if (left->nodetype == nd->nodetype) + ReplaceExprWithLeftChild(nd); + else if (right->nodetype == nd->nodetype) + ReplaceExprWithRightChild(nd); + break; + } + } + } else if (IRO_ExprsSameSemantically(left->u.diadic.right, right->u.diadic.left)) { + if (left->nodetype == right->nodetype) { + switch (left->nodetype) { + case EADD: + if (nd->nodetype == ComplementaryOp[left->nodetype]) { + ReplaceExprWithLeftChild(left); + ReplaceExprWithRightChild(right); + changed = 1; + } + break; + case EMUL: + switch (nd->nodetype) { + case EADD: + case ESUB: + PickCommonsubAtRightLeft(nd); + changed = 3; + break; + } + break; + case EAND: + if (nd->nodetype == EXOR) { + PickCommonsubAtRightLeft(nd); + changed = 3; + break; + } + case EOR: + if (nd->nodetype == left->nodetype) { + ReplaceExprWithLeftChild(left); + changed = 1; + } else if (nd->nodetype == ComplementaryOp[left->nodetype]) { + PickCommonsubAtRightLeft(nd); + changed = 3; + } + break; + } + } else if (left->nodetype == ComplementaryOp[right->nodetype]) { + switch (nd->nodetype) { + case ESUB: + case ESUBV: + if (left->nodetype == EADD) { + nd->nodetype = ComplementaryOp[nd->nodetype]; + ReplaceExprWithLeftChild(left); + ReplaceExprWithRightChild(right); + changed = 1; + } + break; + + case EADD: + case EADDV: + if (left->nodetype == ESUB) { + ReplaceExprWithLeftChild(left); + ReplaceExprWithRightChild(right); + changed = 1; + } + break; + + case EAND: + case EOR: + if (left->nodetype == nd->nodetype) + ReplaceExprWithLeftChild(nd); + else if (right->nodetype == nd->nodetype) + ReplaceExprWithRightChild(nd); + break; + } + } + } else if (IRO_ExprsSameSemantically(left->u.diadic.left, right->u.diadic.right)) { + if (left->nodetype == right->nodetype) { + switch (left->nodetype) { + case EADD: + if (nd->nodetype == ComplementaryOp[left->nodetype]) { + ReplaceExprWithRightChild(left); + ReplaceExprWithLeftChild(right); + changed = 1; + } + break; + case ESUB: + switch (nd->nodetype) { + case EADDV: + case EADD: + nd->nodetype = ComplementaryOp[nd->nodetype]; + ReplaceExprWithRightChild(left); + ReplaceExprWithLeftChild(right); + IRO_SwitchChildren(nd); + changed = 1; + break; + } + break; + case EMUL: + switch (nd->nodetype) { + case EADD: + case ESUB: + PickCommonsubAtLeftRight(nd); + changed = 2; + break; + } + break; + case EAND: + if (nd->nodetype == EXOR) { + PickCommonsubAtLeftRight(nd); + changed = 2; + break; + } + case EOR: + if (nd->nodetype == left->nodetype) { + ReplaceExprWithRightChild(left); + changed = 1; + } else if (nd->nodetype == ComplementaryOp[left->nodetype]) { + PickCommonsubAtLeftRight(nd); + changed = 2; + } + break; + } + } else if (left->nodetype == ComplementaryOp[right->nodetype]) { + switch (nd->nodetype) { + case EADD: + case EADDV: + if (left->nodetype == EADD) { + ReplaceExprWithRightChild(left); + ReplaceExprWithLeftChild(right); + changed = 1; + } + break; + + case ESUB: + case ESUBV: + if (left->nodetype == ESUB) { + ReplaceExprWithMonaminRight(left); + ReplaceExprWithRightChild(right); + changed = 1; + } + break; + + case EAND: + case EOR: + if (left->nodetype == nd->nodetype) + ReplaceExprWithLeftChild(nd); + else if (right->nodetype == nd->nodetype) + ReplaceExprWithRightChild(nd); + break; + } + } + } else if (IRO_ExprsSameSemantically(left->u.diadic.right, right->u.diadic.right)) { + if (left->nodetype == right->nodetype) { + switch (nd->nodetype) { + case ESUB: + switch (left->nodetype) { + case EADD: + case ESUB: + ReplaceExprWithLeftChild(left); + ReplaceExprWithLeftChild(right); + changed = 1; + } + case EADD: + switch (left->nodetype) { + case EMUL: + case ESHL: + PickCommonsubAtRightRight(nd); + changed = 2; + break; + } + break; + case EXOR: + switch (left->nodetype) { + case ESHL: + case ESHR: + case EAND: + PickCommonsubAtRightRight(nd); + changed = 2; + break; + } + break; + case EAND: + case EOR: + if (left->nodetype == nd->nodetype) { + ReplaceExprWithLeftChild(right); + changed = 1; + } else if ( + left->nodetype == ComplementaryOp[nd->nodetype] || + left->nodetype == ESHR || + left->nodetype == ESHL + ) + { + PickCommonsubAtRightRight(nd); + changed = 2; + } + break; + } + } else if (left->nodetype == ComplementaryOp[right->nodetype]) { + switch (nd->nodetype) { + case EADD: + case EADDV: + switch (left->nodetype) { + case EADD: + case ESUB: + ReplaceExprWithLeftChild(left); + ReplaceExprWithLeftChild(right); + changed = 1; + break; + } + break; + + case EAND: + case EOR: + if (left->nodetype == nd->nodetype) + ReplaceExprWithLeftChild(nd); + else if (right->nodetype == nd->nodetype) + ReplaceExprWithRightChild(nd); + break; + } + } + } + + if (changed) { + DoDiadic(nd); + if (changed == 2) + DoDiadic(nd->u.diadic.left); + else if (changed == 3) + DoDiadic(nd->u.diadic.right); + IRO_Dump("remove common op at: %d\n", nd->index); + } + } + } +} + +static void DoTransformations25(IROLinear *nd) { + int changed = 0; + IROLinear *left; + IROLinear *right; + + if (nd->type == IROLinearOp2Arg) { + left = nd->u.diadic.left; + right = nd->u.diadic.right; + + if ( + (left->type == IROLinearOp2Arg && (IS_TYPE_FLOAT(left->u.diadic.left->rtype) || IS_TYPE_FLOAT(left->u.diadic.right->rtype))) || + (right->type == IROLinearOp2Arg && (IS_TYPE_FLOAT(right->u.diadic.left->rtype) || IS_TYPE_FLOAT(right->u.diadic.right->rtype))) + ) + return; + + switch (left->nodetype) { + case ELESS: + case EGREATER: + case ELESSEQU: + case EGREATEREQU: + case EEQU: + case ENOTEQU: + switch (nd->nodetype) { + case EEQU: + if (IRO_IsConstantOne(right)) { + ReplaceExprWithLeftChild(nd); + changed = 1; + } else if (IRO_IsConstantZero(right)) { + left->nodetype = ComplementaryOpLogical[left->nodetype]; + ReplaceExprWithLeftChild(nd); + changed = 1; + } + break; + case ENOTEQU: + if (IRO_IsConstantOne(right)) { + left->nodetype = ComplementaryOpLogical[left->nodetype]; + ReplaceExprWithLeftChild(nd); + changed = 1; + } else if (IRO_IsConstantZero(right)) { + ReplaceExprWithLeftChild(nd); + changed = 1; + } + break; + } + break; + case ELAND: + case ELOR: + switch (nd->nodetype) { + case EEQU: + if (IRO_IsConstantOne(right)) { + ReplaceExprWithLeftChild(nd); + changed = 1; + } + break; + case ENOTEQU: + if (IRO_IsConstantZero(right)) { + ReplaceExprWithLeftChild(nd); + changed = 1; + } + break; + } + break; + } + + if (!changed) { + switch (right->nodetype) { + case ELESS: + case EGREATER: + case ELESSEQU: + case EGREATEREQU: + case EEQU: + case ENOTEQU: + switch (nd->nodetype) { + case EEQU: + if (IRO_IsConstantOne(left)) { + ReplaceExprWithRightChild(nd); + } else if (IRO_IsConstantZero(left)) { + right->nodetype = ComplementaryOpLogical[right->nodetype]; + ReplaceExprWithRightChild(nd); + } + break; + case ENOTEQU: + if (IRO_IsConstantOne(left)) { + right->nodetype = ComplementaryOpLogical[right->nodetype]; + ReplaceExprWithRightChild(nd); + } else if (IRO_IsConstantZero(left)) { + ReplaceExprWithRightChild(nd); + } + break; + } + break; + case ELAND: + case ELOR: + switch (nd->nodetype) { + case EEQU: + if (IRO_IsConstantOne(left)) { + ReplaceExprWithRightChild(nd); + } + break; + case ENOTEQU: + if (IRO_IsConstantZero(left)) { + ReplaceExprWithRightChild(nd); + } + break; + } + break; + } + } + } +} + +static Boolean isOrderingOperator(ENodeType op) { + switch (op) { + case ELAND: + case ELOR: + case ECOMMA: + case ECOND: + case ECONDASS: + return 1; + default: + return 0; + } +} + +static void RemoveUnreffed(IROLinear *nd) { + if (!(nd->flags & IROLF_Reffed)) { + switch (nd->type) { + case IROLinearOperand: + IRO_NopNonSideEffects(nd, 0); + break; + case IROLinearOp1Arg: + case IROLinearOp2Arg: + case IROLinearOp3Arg: + case IROLinearFunccall: + if (!isOrderingOperator(nd->nodetype)) + IRO_NopNonSideEffects(nd, 0); + break; + } + } +} + +static void RemoveRedundantMonadicOp(IROLinear *nd) { + IROLinear *nd2; + IROLinear *nd3; + + if (nd->type == IROLinearOp1Arg && (nd2 = IRO_LocateFather(nd)) && nd2->nodetype == nd->nodetype) { + switch (nd->nodetype) { + case ELOGNOT: + if ((nd3 = IRO_LocateFather(nd2))) { + if ( + nd3->rtype && + TYPE_INTEGRAL(nd3->rtype)->integral == IT_BOOL && + nd->u.monadic->rtype && + TYPE_INTEGRAL(nd->u.monadic->rtype)->integral == IT_BOOL + ) + goto remove; + + if (nd3->type == IROLinearIf) + goto remove; + if (nd3->type == IROLinearIfNot) + goto remove; + if (nd3->type == IROLinearOp3Arg && nd == nd3->u.args3.a) + goto remove; + + switch (nd3->nodetype) { + case ELOGNOT: + case ELAND: + case ELOR: + goto remove; + } + } + + if (nd->u.monadic->type == IROLinearOp1Arg || nd->u.monadic->type == IROLinearOp2Arg) { + switch (nd->u.monadic->nodetype) { + case ELOGNOT: + case ELESS: + case EGREATER: + case ELESSEQU: + case EGREATEREQU: + case EEQU: + case ENOTEQU: + case ELAND: + case ELOR: + goto remove; + } + } + break; + + case EMONMIN: + case EBINNOT: + remove: + IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd2, nd->u.monadic); + nd2->type = IROLinearNop; + nd->type = IROLinearNop; + break; + + case ETYPCON: + if (TYPE_INTEGRAL(nd->rtype)->integral == IT_FLOAT) { + switch (TYPE_INTEGRAL(nd2->rtype)->integral) { + case IT_DOUBLE: + case IT_LONGDOUBLE: + switch (TYPE_INTEGRAL(nd->u.monadic->rtype)->integral) { + case IT_BOOL: + case IT_CHAR: + case IT_SCHAR: + case IT_UCHAR: + case IT_SHORT: + case IT_USHORT: + nd->type = IROLinearNop; + nd2->u.monadic = nd->u.monadic; + break; + } + break; + } + } + break; + } + } +} + +static void ReverseOpForMonmin(IROLinear *nd) { + IROLinear *father; + + if ( + nd->type == IROLinearOp1Arg && + nd->nodetype == EMONMIN && + (father = IRO_LocateFather(nd)) && + father->type == IROLinearOp2Arg && + father->u.diadic.right == nd + ) + { + switch (father->nodetype) { + case EADDV: + case ESUBV: + case EADD: + case ESUB: + case EADDASS: + case ESUBASS: + father->nodetype = ComplementaryOp[father->nodetype]; + nd->type = IROLinearNop; + father->u.diadic.right = nd->u.monadic; + break; + } + } +} + +static void DoDiadic(IROLinear *nd) { + RemoveUnreffed(nd); + DoTransformations(nd); + DoTransformations11(nd); + DoTransformations12(nd); + DoTransformations13(nd); + DoTransformations21(nd); + DoTransformations22(nd); + DoTransformations23(nd); + DoTransformations24(nd); + DoTransformations25(nd); +} + +void IRO_DoTransformations(void) { + IROLinear *nd; + + for (nd = IRO_FirstLinear; nd; nd = nd->next) { + switch (nd->type) { + case IROLinearOp2Arg: + DoDiadic(nd); + break; + case IROLinearOp1Arg: + RemoveUnreffed(nd); + RemoveRedundantMonadicOp(nd); + ReverseOpForMonmin(nd); + break; + case IROLinearOperand: + RemoveUnreffed(nd); + break; + } + } + + IRO_CheckForUserBreak(); +} + +static Boolean ReconcileAssignments(IROLinear *nd1, IROLinear *nd2, IROList *list) { + IROLinear *copy; + Boolean result = 0; + int argCount; + int i; + IROLinear *tmp; + + if ( + (nd2->type == IROLinearOp1Arg && nd2->nodetype == ETYPCON) && + !(nd1->type == IROLinearOp1Arg && nd1->nodetype == ETYPCON) && + ReconcileAssignments(nd1, nd2->u.monadic, list) + ) + { + result = 1; + } + + if ( + (nd1->type == IROLinearOp1Arg && nd1->nodetype == ETYPCON) && + !(nd2->type == IROLinearOp1Arg && nd2->nodetype == ETYPCON) && + ReconcileAssignments(nd1->u.monadic, nd2, list) + ) + { + copy = IRO_NewLinear(IROLinearOp1Arg); + *copy = *nd2; + copy->index = IRO_NumLinear++; + copy->type = IROLinearOp1Arg; + copy->nodetype = ETYPCON; + copy->rtype = nd1->rtype; + copy->next = NULL; + copy->u.monadic = list->tail; + IRO_AddToList(copy, list); + result = 1; + } + + if (nd1->type == nd2->type && nd1->nodetype == nd2->nodetype) { + copy = IRO_NewLinear(IROLinearNop); + *copy = *nd2; + copy->index = IRO_NumLinear++; + copy->rtype = nd1->rtype; + copy->next = NULL; + switch (nd1->type) { + case IROLinearOperand: + if (nd1->u.node->type == nd2->u.node->type) { + if (!(nd1->u.node->type == EOBJREF && nd1->u.node->data.objref != nd2->u.node->data.objref)) + result = 1; + } + break; + + case IROLinearOp1Arg: + if (ReconcileAssignments(nd1->u.monadic, nd2->u.monadic, list)) { + copy->u.monadic = list->tail; + result = 1; + } + break; + + case IROLinearOp2Arg: + tmp = list->tail; + if (ReconcileAssignments(nd1->u.diadic.left, nd2->u.diadic.left, list)) { + copy->u.diadic.left = list->tail; + if (ReconcileAssignments(nd1->u.diadic.right, nd2->u.diadic.right, list)) { + copy->u.diadic.right = list->tail; + result = 1; + } + } + + if (!result && !IRO_HasSideEffect(nd1) && !IRO_HasSideEffect(nd2)) { + if (nd1->nodetype == EMUL || nd1->nodetype == EADD || nd1->nodetype == EAND || nd1->nodetype == EXOR || nd1->nodetype == EOR) { + list->tail = tmp; + if (ReconcileAssignments(nd1->u.diadic.left, nd2->u.diadic.right, list)) { + copy->u.diadic.right = list->tail; + if (ReconcileAssignments(nd1->u.diadic.right, nd2->u.diadic.left, list)) { + copy->u.diadic.left = list->tail; + result = 1; + } + } + } + } + break; + + case IROLinearOp3Arg: + if (ReconcileAssignments(nd1->u.args3.c, nd2->u.args3.c, list)) { + copy->u.args3.c = list->tail; + if (ReconcileAssignments(nd1->u.args3.b, nd2->u.args3.b, list)) { + copy->u.args3.b = list->tail; + if (ReconcileAssignments(nd1->u.args3.a, nd2->u.args3.a, list)) { + copy->u.args3.a = list->tail; + result = 1; + } + } + } + break; + + case IROLinearFunccall: + argCount = nd1->u.funccall.argCount; + if (argCount == nd2->u.funccall.argCount) { + result = 1; + copy->u.funccall.args = oalloc(sizeof(IROLinear *) * argCount); + for (i = argCount - 1; i >= 0; i--) { + if (!ReconcileAssignments(nd1->u.funccall.args[i], nd2->u.funccall.args[i], list)) { + result = 0; + break; + } + copy->u.funccall.args[i] = list->tail; + } + + if (result) { + if (!ReconcileAssignments(nd1->u.funccall.linear8, nd2->u.funccall.linear8, list)) { + result = 0; + break; + } + copy->u.funccall.linear8 = list->tail; + } + } + break; + } + + if (result) + IRO_AddToList(copy, list); + } + + return result; +} + +static IROLinear *FrontendTransformSelfAssignmentToAssignment(IROLinear *nd) { + Statement *stmt; + IROList list; + IROLinearIRSave save; + + IRO_SaveLinearIR(&save); + + IRO_InitList(&list); + IRO_DuplicateExpr(nd, &list); + + stmt = IRO_Delinearize(NULL, list.head); + CError_ASSERT(3550, stmt); + CError_ASSERT(3552, stmt->expr); + stmt->expr = CIRTrans_TransformOpAss(stmt->expr); + CError_ASSERT(3557, stmt->expr); + + if (DoLinearize) + IRO_PreLinearize(stmt); + IRO_Linearize(stmt); + + IRO_InitList(&list); + list.head = IRO_FirstLinear; + list.tail = IRO_LastLinear; + + IRO_RestoreLinearIR(&save); + + for (nd = list.head; nd; nd = nd->next) { + if (!(nd->flags & IROLF_Reffed) && IRO_IsAssignment(nd)) + break; + } + + return nd; +} + +static Type *PromotedIntegralType(Type *type) { + CError_ASSERT(3586, IS_TYPE_ENUM(type) || IS_TYPE_INT(type)); + + if (IS_TYPE_ENUM(type)) + type = TYPE_ENUM(type)->enumtype; + + if (TYPE_INTEGRAL(type)->integral < IT_INT) { + if (IRO_IsUnsignedType(type)) + return TYPE(&stunsignedint); + else + return TYPE(&stsignedint); + } else { + return type; + } +} + +static Boolean TransformMonadicSelfAssignmentToDiadicSelfAssignment(IROLinear *nd) { + ENodeType t; + ENodeType newtype; + IROLinear *incExpr; + IROLinear *varExpr; + + t = nd->nodetype; + + if (IRO_IsAssignment(nd) && IRO_IsModifyOp[t]) { + incExpr = NULL; + varExpr = NULL; + newtype = MAXEXPR; + + if ( + nd->type == IROLinearOp1Arg && + (t == EPOSTINC || t == EPOSTDEC || t == EPREINC || t == EPREDEC) && + (!(nd->flags & IROLF_Reffed) || t == EPREINC || t == EPREDEC) + ) + { + Type *type = nd->rtype; + TypeType typetype = type->type; + varExpr = nd->u.monadic; + if (typetype == TYPEINT || typetype == TYPEENUM) { + incExpr = IRO_NewIntConst(cint64_one, PromotedIntegralType(type)); + } else if (typetype == TYPEPOINTER || typetype == TYPEARRAY || typetype == TYPEMEMBERPOINTER) { + Type *inner = NULL; + CInt64 val = cint64_zero; + + if (typetype == TYPEPOINTER || typetype == TYPEARRAY) + inner = TPTR_TARGET(type); + else if (typetype == TYPEMEMBERPOINTER) + inner = TYPE_MEMBER_POINTER(type)->ty1; + + if (inner) + CInt64_SetLong(&val, inner->size); + + if (!CInt64_IsZero(&val)) { + incExpr = IRO_NewIntConst(val, TYPE(&stsignedlong)); + } else { + return 0; + } + } else if (typetype == TYPEFLOAT) { + Float fval; + fval = CMach_CalcFloatConvertFromInt(type, cint64_one); + incExpr = IRO_NewFloatConst(fval, nd->rtype); + } else { + return 0; + } + + if (t == EPOSTINC || t == EPREINC) + newtype = EADDASS; + else + newtype = ESUBASS; + } + + if ( + varExpr && + incExpr && + newtype != MAXEXPR && + varExpr->u.diadic.left && + varExpr->u.diadic.left->type == IROLinearOperand && + varExpr->u.diadic.left->u.node && + varExpr->u.diadic.left->u.node->type == EOBJREF && + !IRO_HasSideEffect(varExpr) + ) + { + incExpr->flags |= IROLF_Reffed; + nd->nodetype = newtype; + nd->u.diadic.right = incExpr; + nd->type = IROLinearOp2Arg; + IRO_Paste(incExpr, incExpr, nd); + return 1; + } + } + + return 0; +} + +Boolean IRO_TransformSelfAssignmentToAssignment(IROLinear *nd) { + ENodeType nonAssOp; + IROLinear *left; + IROLinear *right; + ENodeType nodetype; + IROLinear *nonAss; + IROLinear *dupLeft; + IROLinear *last; + IROList list1; + IROList list2; + + nodetype = nd->nodetype; + if ( + IRO_IsAssignment(nd) && + IRO_IsModifyOp[nodetype] && + nd->type == IROLinearOp1Arg && + TransformMonadicSelfAssignmentToDiadicSelfAssignment(nd) + ) + nodetype = nd->nodetype; + + if ( + IRO_IsAssignment(nd) && + IRO_IsModifyOp[nodetype] && + nd->type == IROLinearOp2Arg && + IRO_NonAssignmentOp[nodetype] != MAXEXPR + ) + { + left = nd->u.diadic.left; + right = nd->u.diadic.right; + nonAssOp = IRO_NonAssignmentOp[nodetype]; + if ( + left && + right && + nonAssOp != MAXEXPR && + left->u.monadic && + left->u.monadic->type == IROLinearOperand && + left->u.monadic->u.node && + left->u.monadic->u.node->type == EOBJREF && + !IRO_HasSideEffect(left) + ) + { + IRO_InitList(&list1); + dupLeft = IRO_DuplicateExpr(left, &list1); + + if (left->rtype != right->rtype) { + IROLinear *tmp = IRO_NewLinear(IROLinearOp1Arg); + tmp->nodetype = ETYPCON; + tmp->flags |= IROLF_Reffed; + tmp->rtype = right->rtype; + tmp->index = ++IRO_NumLinear; + tmp->u.monadic = dupLeft; + IRO_AddToList(tmp, &list1); + dupLeft = tmp; + } + + nonAss = IRO_NewLinear(IROLinearOp2Arg); + nonAss->nodetype = nonAssOp; + nonAss->flags |= IROLF_Reffed; + nonAss->rtype = dupLeft->rtype; + nonAss->index = ++IRO_NumLinear; + nonAss->u.diadic.left = dupLeft; + nonAss->u.diadic.right = right; + IRO_AddToList(nonAss, &list1); + + if (left->rtype != right->rtype) { + IROLinear *tmp = IRO_NewLinear(IROLinearOp1Arg); + tmp->nodetype = ETYPCON; + tmp->flags |= IROLF_Reffed; + tmp->rtype = left->rtype; + tmp->index = ++IRO_NumLinear; + tmp->u.monadic = nonAss; + IRO_AddToList(tmp, &list1); + nonAss = tmp; + } + + IRO_InitList(&list2); + last = FrontendTransformSelfAssignmentToAssignment(nd); + if ( + last && + last->type == IROLinearOp2Arg && + ReconcileAssignments(last->u.diadic.right, nonAss, &list2) + ) + { + IRO_NopOut(nd->u.diadic.right); + nd->nodetype = EASS; + nd->u.diadic.right = list2.tail; + nd->type = IROLinearOp2Arg; + IRO_Paste(list2.head, list2.tail, nd); + return 1; + } + } + } + + return 0; +} + +static void AddAddend(ENode *expr) { + if (expr->type == EADD) { + AddAddend(expr->data.diadic.left); + AddAddend(expr->data.diadic.right); + } else { + ENodeList *list = oalloc(sizeof(ENodeList)); + list->node = expr; + list->next = NULL; + + if (FirstAddend) + LastAddend->next = list; + else + FirstAddend = list; + LastAddend = list; + } +} + +static ENode *CombineConstants(ENode *expr) { + ENode *addend; + ENodeList *el; + ENode *result; + ENode *var; + Type *type; + ENode *tmp; + ENodeList *prev; + CInt64 val; + + FirstAddend = LastAddend = NULL; + AddAddend(expr->data.diadic.left); + AddAddend(expr->data.diadic.right); + + // these variable names are courtesy of the resource fork in abort_exit.c + el = FirstAddend; + prev = NULL; + var = NULL; + while (el) { + addend = el->node; + if (addend->type == EOBJREF) { + var = addend; + if (prev) + prev->next = el->next; + else + FirstAddend = el->next; + break; + } + prev = el; + el = el->next; + } + + if (!var) { + el = FirstAddend; + prev = NULL; + while (el) { + addend = el->node; + if (addend->type == EINDIRECT) { + var = addend; + if (prev) + prev->next = el->next; + else + FirstAddend = el->next; + break; + } + prev = el; + el = el->next; + } + } + + prev = NULL; + CInt64_SetLong(&val, 0); + type = NULL; + + for (el = FirstAddend; el; el = el->next) { + addend = el->node; + if (addend->type == EINTCONST && addend->rtype) { + if (!type || type->size < addend->rtype->size) + type = addend->rtype; + val = CInt64_Add(val, addend->data.intval); + if (prev) + prev->next = el->next; + else + FirstAddend = el->next; + } else if (addend->type == EMUL && addend->data.diadic.right->type == EINTCONST && addend->rtype) { + if (!type || type->size < addend->rtype->size) + type = addend->rtype; + + tmp = addend->data.diadic.left; + if (tmp->type == EADD && tmp->data.diadic.right->type == EINTCONST) { + val = CInt64_Add(val, CInt64_MulU(tmp->data.diadic.right->data.intval, addend->data.diadic.right->data.intval)); + addend->data.diadic.left = tmp->data.diadic.left; + } + prev = el; + } else { + prev = el; + } + } + + result = NULL; + if (var) { + result = var; + if (!CInt64_IsZero(&val)) { + result = IRO_NewENode(EADD); + result->data.diadic.left = var; + result->data.diadic.right = IRO_NewENode(EINTCONST); + result->data.diadic.right->data.intval = val; + result->data.diadic.right->rtype = type; + result->rtype = var->rtype; + result->cost = 1; + CInt64_SetLong(&val, 0); + } + } + + for (el = FirstAddend; el; el = el->next) { + addend = el->node; + if (result) { + tmp = IRO_NewENode(EADD); + tmp->data.diadic.left = result; + tmp->data.diadic.right = addend; + tmp->cost = result->cost + 1; + tmp->rtype = result->rtype; + result = tmp; + } else { + result = addend; + } + } + + if (!CInt64_IsZero(&val)) { + tmp = IRO_NewENode(EADD); + tmp->data.diadic.left = result; + tmp->data.diadic.right = IRO_NewENode(EINTCONST); + tmp->data.diadic.right->data.intval = val; + tmp->data.diadic.right->rtype = type; + tmp->cost = result->cost + 1; + tmp->rtype = result->rtype; + result = tmp; + } + + return result; +} + +static ENode *TransformExprNode(ENode *expr) { + ENode *left; + ENode *right; + + switch (expr->type) { + case EINDIRECT: + if (ENODE_IS(expr->data.monadic, EADD)) + expr->data.monadic = CombineConstants(expr->data.monadic); + break; + + case EMUL: + case EADD: + case EAND: + case EXOR: + case EOR: + if ( + IS_TYPE_INT(expr->rtype) && + !ENODE_IS(right = expr->data.diadic.right, EINTCONST) && + ENODE_IS(left = expr->data.diadic.left, EINTCONST) + ) + { + expr->data.diadic.left = right; + expr->data.diadic.right = left; + } + break; + + case EEQU: + case ENOTEQU: + if ( + IS_TYPE_INT(expr->rtype) && + !ENODE_IS(left = expr->data.diadic.right, EINTCONST) && + ENODE_IS(right = expr->data.diadic.left, EINTCONST) + ) + { + expr->data.diadic.left = left; + expr->data.diadic.right = right; + } + + if ( + ENODE_IS(expr->data.diadic.right, EINTCONST) && + ENODE_IS(left = expr->data.diadic.left, EBINNOT) + ) + { + expr->data.diadic.left = left->data.monadic; + left->data.monadic = expr->data.diadic.right; + expr->data.diadic.right = left; + } + + break; + } + + return expr; +} + +static ENode *TransformExprTree(ENode *expr) { + ENodeList *list; + + switch (expr->type) { + ENODE_CASE_MONADIC: + expr->data.monadic = TransformExprTree(expr->data.monadic); + break; + + ENODE_CASE_DIADIC_ALL: + expr->data.diadic.left = TransformExprTree(expr->data.diadic.left); + expr->data.diadic.right = TransformExprTree(expr->data.diadic.right); + break; + + case EFUNCCALL: + case EFUNCCALLP: + TransformExprTree(expr->data.funccall.funcref); + for (list = expr->data.funccall.args; list; list = list->next) + TransformExprTree(list->node); + break; + + case ECOND: + TransformExprTree(expr->data.cond.cond); + TransformExprTree(expr->data.cond.expr1); + TransformExprTree(expr->data.cond.expr2); + break; + + case ENULLCHECK: + TransformExprTree(expr->data.nullcheck.nullcheckexpr); + TransformExprTree(expr->data.nullcheck.condexpr); + break; + } + + return TransformExprNode(expr); +} + +static void FoldConstantsinAssociativeExprs(ENode *expr) { + short nodetype1; + short nodetype2; + short nodetype3; + Boolean changed; + short op; + CInt64 val1; + CInt64 val2; + CInt64 tmpval; + + if ( + ( + expr->type == EADD || + expr->type == EMUL || + expr->type == EAND || + expr->type == EXOR || + expr->type == EOR || + expr->type == ESHL || + expr->type == ESHR + ) && + IS_TYPE_INT(expr->rtype) && + expr->data.diadic.right->type == EINTCONST + ) + { + do { + changed = 0; + + if ( + expr->data.diadic.left->type == expr->type && + expr->data.diadic.left->data.diadic.right->type == EINTCONST + ) + { + val1 = expr->data.diadic.right->data.intval; + val2 = expr->data.diadic.left->data.diadic.right->data.intval; + switch (expr->type) { + case EADD: + case ESHL: + op = '+'; + break; + case ESHR: + op = '+'; + if (!IRO_IsUnsignedType(expr->rtype)) { + CInt64_SetLong(&tmpval, expr->rtype->size * 8); + if (CInt64_GreaterEqualU(val1, tmpval) || CInt64_GreaterEqualU(val2, tmpval)) + return; + + if (CInt64_GreaterEqualU(CMach_CalcIntDiadic(expr->rtype, val1, '+', val2), tmpval)) { + val1 = CInt64_Sub(tmpval, cint64_one); + val2 = cint64_zero; + } + } + break; + case EMUL: + op = '*'; + break; + case EAND: + op = '&'; + break; + case EOR: + op = '|'; + break; + case EXOR: + op = '^'; + break; + default: + return; + } + + expr->data.diadic.right->data.intval = CMach_CalcIntDiadic(expr->rtype, val1, op, val2); + expr->data.diadic.left = expr->data.diadic.left->data.diadic.left; + changed = 1; + } else if ( + ((nodetype1 = expr->type) == EAND || nodetype1 == EOR) && + ((nodetype2 = expr->data.diadic.left->type) == EAND || nodetype2 == EOR) && + ((nodetype3 = expr->data.diadic.left->data.diadic.left->type) == EAND || nodetype3 == EOR) && + expr->data.diadic.left->data.diadic.left->data.diadic.right->type == EINTCONST + ) + { + val1 = expr->data.diadic.right->data.intval; + if (CInt64_Equal(val1, expr->data.diadic.left->data.diadic.left->data.diadic.right->data.intval)) { + if (nodetype1 == nodetype3) { + expr->data.diadic.left->data.diadic.left = expr->data.diadic.left->data.diadic.left->data.diadic.left; + changed = 1; + } else if (nodetype2 == nodetype3) { + *expr = *expr->data.diadic.right; + changed = 1; + } else { + expr->data.diadic.left = expr->data.diadic.left->data.diadic.right; + changed = 1; + } + } + } + } while (changed); + } +} + +static void TransformExprTree1(ENode *expr) { + ENodeList *list; + + switch (expr->type) { + ENODE_CASE_MONADIC: + TransformExprTree1(expr->data.monadic); + break; + + ENODE_CASE_DIADIC_ALL: + TransformExprTree1(expr->data.diadic.left); + TransformExprTree1(expr->data.diadic.right); + break; + + case EFUNCCALL: + case EFUNCCALLP: + TransformExprTree1(expr->data.funccall.funcref); + for (list = expr->data.funccall.args; list; list = list->next) + TransformExprTree1(list->node); + break; + + case ECOND: + TransformExprTree1(expr->data.cond.cond); + TransformExprTree1(expr->data.cond.expr1); + TransformExprTree1(expr->data.cond.expr2); + break; + + case ENULLCHECK: + TransformExprTree1(expr->data.nullcheck.nullcheckexpr); + TransformExprTree1(expr->data.nullcheck.condexpr); + break; + } + + FoldConstantsinAssociativeExprs(expr); +} + +static int RemoveRedundantBitOperations(ENode *expr) { + Boolean a; + Boolean b; + + if (expr->type == ExprType) { + a = RemoveRedundantBitOperations(expr->data.diadic.left); + b = RemoveRedundantBitOperations(expr->data.diadic.right); + return a & b; + } + + if (expr->type == EINDIRECT) { + if (expr->data.monadic->type == EOBJREF) { + if (!OperandObject) { + OperandObject = expr->data.monadic->data.objref; + IndirectRef = expr; + return 1; + } else { + return expr->data.monadic->data.objref == OperandObject; + } + } else { + return 0; + } + } + + if (expr->type == EINTCONST) { + if (FirstTime) { + OperandConst = expr->data.intval; + FirstTime = 0; + } else if (ExprType == EAND) { + OperandConst = CInt64_And(expr->data.intval, OperandConst); + } else if (ExprType == EOR) { + OperandConst = CInt64_Or(expr->data.intval, OperandConst); + } else if (ExprType == EXOR) { + OperandConst = CInt64_Xor(expr->data.intval, OperandConst); + } + return 1; + } + + return 0; +} + +static void TransformExprTree2(ENode *expr) { + ENodeList *list; + + switch (expr->type) { + ENODE_CASE_MONADIC: + TransformExprTree2(expr->data.monadic); + break; + + ENODE_CASE_DIADIC_ALL: + TransformExprTree2(expr->data.diadic.left); + TransformExprTree2(expr->data.diadic.right); + break; + + case EFUNCCALL: + case EFUNCCALLP: + TransformExprTree2(expr->data.funccall.funcref); + for (list = expr->data.funccall.args; list; list = list->next) + TransformExprTree2(list->node); + break; + + case ECOND: + TransformExprTree2(expr->data.cond.cond); + TransformExprTree2(expr->data.cond.expr1); + TransformExprTree2(expr->data.cond.expr2); + break; + + case ENULLCHECK: + TransformExprTree2(expr->data.nullcheck.nullcheckexpr); + TransformExprTree2(expr->data.nullcheck.condexpr); + break; + } + + if ( + ENODE_IS3(expr, EAND, EOR, EXOR) && + (expr->type == expr->data.diadic.left->type || expr->type == expr->data.diadic.right->type) + ) + { + OperandObject = NULL; + ExprType = expr->type; + FirstTime = 1; + IndirectRef = NULL; + + if (RemoveRedundantBitOperations(expr)) { + expr->data.diadic.left = IndirectRef; + expr->data.diadic.right->type = EINTCONST; + expr->data.diadic.right->data.intval = OperandConst; + } + } +} + +static void PullOutPostOps(Statement *stmt, ENode **pExpr) { + ENode *ind; + ENode *inner; + Statement *newStmt; + + switch ((*pExpr)->type) { + ENODE_CASE_MONADIC: + if ((*pExpr)->type != EFORCELOAD) + PullOutPostOps(stmt, &(*pExpr)->data.monadic); + + if (ENODE_IS2(*pExpr, EPOSTINC, EPOSTDEC)) { + inner = (*pExpr)->data.monadic; + if ( + ENODE_IS(inner, EINDIRECT) && + inner->rtype && + !CParser_IsVolatile(inner->rtype, ENODE_QUALS(inner)) && + ENODE_IS(inner->data.monadic, EOBJREF) && + !is_volatile_object(inner->data.monadic->data.objref) + ) + { + newStmt = lalloc(sizeof(Statement)); + memset(newStmt, 0, sizeof(Statement)); + newStmt->type = ST_EXPRESSION; + newStmt->expr = *pExpr; + newStmt->dobjstack = stmt->dobjstack; + newStmt->sourceoffset = stmt->sourceoffset; + newStmt->sourcefilepath = stmt->sourcefilepath; + newStmt->value = stmt->value; + newStmt->flags = stmt->flags; + newStmt->next = stmt->next; + stmt->next = newStmt; + + ind = IRO_NewENode(EINDIRECT); + *ind = *inner; + ind->data.monadic = IRO_NewENode(EOBJREF); + *ind->data.monadic = *inner->data.monadic; + *pExpr = ind; + } + } + break; + + ENODE_CASE_DIADIC_ALL: + if (ENODE_IS(*pExpr, ECOND)) + break; + if (ENODE_IS(*pExpr, ECOMMA)) + break; + if (ENODE_IS(*pExpr, ELOR)) + break; + if (ENODE_IS(*pExpr, ELAND)) + break; + if (ENODE_IS(*pExpr, ENULLCHECK)) + break; + PullOutPostOps(stmt, &(*pExpr)->data.diadic.left); + PullOutPostOps(stmt, &(*pExpr)->data.diadic.right); + break; + } +} + +void IRO_TransformTree(Statement *statements) { + Statement *stmt; + Statement *next; + + for (stmt = statements; stmt; stmt = next) { + next = stmt->next; + switch (stmt->type) { + case ST_EXPRESSION: + case ST_SWITCH: + case ST_IFGOTO: + case ST_IFNGOTO: + case ST_RETURN: + if (stmt->expr) { + stmt->expr = TransformExprTree(stmt->expr); + TransformExprTree2(stmt->expr); + TransformExprTree1(stmt->expr); + } + break; + } + } + + IRO_CheckForUserBreak(); +} diff --git a/compiler_and_linker/unsorted/IroUnrollLoop.c b/compiler_and_linker/unsorted/IroUnrollLoop.c index f5c4fb0..5bbe490 100644 --- a/compiler_and_linker/unsorted/IroUnrollLoop.c +++ b/compiler_and_linker/unsorted/IroUnrollLoop.c @@ -1,8 +1,38 @@ #include "compiler/IroUnrollLoop.h" +#include "compiler/CError.h" +#include "compiler/IroFlowgraph.h" +#include "compiler/IroLinearForm.h" #include "compiler/IroUtil.h" +#include "compiler/LoopDetection.h" +#include "compiler/IroLoop.h" +#include "compiler/IroDump.h" +#include "compiler/IroVars.h" +#include "compiler/CFunc.h" +#include "compiler/CMachine.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +typedef struct LoopList { + UInt8 flags; + BitVector *bv; + struct LoopList *next; + IRONode *fnode; + int xE; +} LoopList; +#ifdef __MWERKS__ +#pragma options align=reset +#endif // forward decls static void IRO_FindLoops_Unroll(void); +static void LoopUnroll(int count, IRONode *fnode); +static int IsLoopUnrollable(IROLoop *loop); +static int IsDifferenceOfTermsConstant(IROAddrRecord *lowerRec, IROAddrRecord *upperRec, int isUnsigned, CInt64 *pval); +static IROLinear *BuildOrigIterationCount_DoWhile(IROList *list, IROLoop *loop); +static IROLinear *BuildPreAlignTemp(IROLoopInd *ind, UInt32 unrollFactor, IROList *list); +static IROLinear *BuildNewFinalvalue_DoWhile(IROLinear *iterCount, UInt32 unrollFactor, IROList *list, IROLoop *loop); +static IROLinear *BuildUnrolledFinalvalue_DoWhile(IROLinear *iterCount, UInt32 unrollFactor, IROList *list, IROLoop *loop); void IRO_LoopUnroller(void) { VectorPhaseCalledFromUnroll = 1; @@ -11,85 +41,2265 @@ void IRO_LoopUnroller(void) { } static void IRO_FindLoops_Unroll(void) { + IRONode *fnode; + IRONode *pred; + UInt16 i; + UInt16 flag; + LoopList *list; + LoopList *list2; + + fnode = IRO_FirstNode; + LoopList_First = NULL; + + while (fnode) { + flag = 0; + for (i = 0; i < fnode->numpred; i++) { + pred = IRO_NodeTable[fnode->pred[i]]; + if (Bv_IsBitSet(fnode->index, pred->dom)) { + if (!flag) { + Bv_AllocVector(&InLoop, IRO_NumNodes + 1); + Bv_Clear(InLoop); + Bv_SetBit(fnode->index, InLoop); + } + flag = 1; + Bv_SetBit(pred->index, InLoop); + if (pred != fnode) + AddPreds(pred); + } + } + + if (flag) { + if (!LoopList_First) { + list = oalloc(sizeof(LoopList)); + list->next = NULL; + } else { + list = oalloc(sizeof(LoopList)); + list->next = LoopList_First; + } + LoopList_First = list; + + Bv_AllocVector(&list->bv, IRO_NumNodes + 1); + list->flags |= 1; + Bv_Copy(InLoop, list->bv); + list->fnode = fnode; + list->xE = 0; + } + + fnode = fnode->nextnode; + } + + list = LoopList_First; + Bv_AllocVector(&LoopTemp, IRO_NumNodes + 1); + while (list) { + for (list2 = LoopList_First; list2; list2 = list2->next) { + if (list2 != list) { + IRO_Dump(" header = %d \n", list2->fnode->index); + IRO_Dump(" l1 bit vector=\n"); + IRO_DumpBits("", list2->bv); + IRO_Dump(" l bit vector=\n"); + IRO_DumpBits("", list->bv); + if (Bv_IsSubset(list->bv, list2->bv)) + list2->flags &= ~1; + } + } + list = list->next; + } + + for (list = LoopList_First; list; list = list->next) { + if (list->flags & 1) { + IRONode *listfnode; + Bv_Copy(list->bv, InLoop); + listfnode = list->fnode; + IRO_Dump("IRO_FindLoops_Unroll:Found loop with header %d\n", listfnode->index); + IRO_DumpBits("Loop includes: ", InLoop); + LoopUnroll(copts.loop_unroll_count, listfnode); + IRO_UpdateFlagsOnInts(); + } + } } -static void CheckConstant() { +static int CheckConstant(CInt64 a, CInt64 b, CInt64 *result) { + CInt64 shl = cint64_zero; + CInt64 work = cint64_zero; + CInt64 and = cint64_zero; + CInt64 i; + + for (i = cint64_zero; CInt64_Less(i, a); i = CInt64_Add(i, cint64_one)) { + shl = CInt64_Shl(b, i); + and = CInt64_And(shl, work); + if (CInt64_NotEqual(and, cint64_zero)) + return 0; + work = CInt64_Or(shl, work); + } + + *result = work; + return 1; } -static void UnrollWhileLoopBody() { +typedef struct LoopPattern { + IROLinear *nd0; + IROLinear *nd4; + Type *type; + IROLinear *ndC; + IROLinear *nd10; + CInt64 val14; + CInt64 val1C; +} LoopPattern; + +static void UnrollWhileLoopBody(IRONode *header, IRONode *fnode2, IRONode *fnode3, IROLoop *loop, LoopPattern *pattern, UInt32 unrollFactor) { + IRONode *scan; + int pass; + IROLinear *firstnode; + IROLinear *lastnd; + IROLinear *nd; + IROLinear *nd1; + IROLinear *nd2; + IROLinear *nd3; + IROLinear *nd4; + IROLinear *nd5; + IROLinear *nd6; + IROLinear *nd8; + IROLinear *nd7; + ENode *expr; + IROList list; + CInt64 zero; + CInt64 shiftval; + + CInt64_SetLong(&zero, 0); + + pass = 0; + + do { + firstnode = NULL; + for (scan = fnode3; scan && scan != header; scan = scan->nextnode) { + IRO_InitList(&list); + lastnd = scan->last; + nd = scan->first; + while (1) { + if (nd->stmt) + nd->stmt->flags |= StmtFlag_10; + + if ( + (nd->index < loop->index20 || nd->index > loop->index24) && + nd->type != IROLinearLabel && + nd->type != IROLinearNop && + !(nd->flags & IROLF_Reffed) + ) + { + CError_ASSERT(345, nd->nodetype == EORASS || nd->nodetype == EANDASS || nd->nodetype == EXORASS); + + IRO_DuplicateExpr(pattern->nd0, &list); + nd1 = list.tail; + + shiftval = cint64_one; + shiftval = CInt64_Shl(shiftval, pattern->val1C); + + nd2 = IRO_NewLinear(IROLinearOperand); + nd2->index = ++IRO_NumLinear; + nd2->rtype = pattern->nd0->rtype; + expr = IRO_NewENode(EINTCONST); + expr->rtype = pattern->nd0->rtype; + CInt64_SetLong(&expr->data.intval, pass * CInt64_GetULong(&shiftval)); + nd2->u.node = expr; + IRO_AddToList(nd2, &list); + + IRO_DuplicateExpr(pattern->nd4, &list); + + nd3 = IRO_NewLinear(IROLinearOp2Arg); + nd3->index = ++IRO_NumLinear; + nd3->nodetype = EADD; + nd3->rtype = pattern->type; + nd3->u.diadic.left = list.tail; + nd3->u.diadic.right = nd2; + IRO_AddToList(nd3, &list); + + nd4 = IRO_NewLinear(IROLinearOp2Arg); + nd4->index = ++IRO_NumLinear; + nd4->nodetype = EADD; + nd4->rtype = pattern->type; + nd4->u.diadic.left = nd3; + nd4->u.diadic.right = nd1; + IRO_AddToList(nd4, &list); + + nd5 = IRO_NewLinear(IROLinearOp1Arg); + nd5->index = ++IRO_NumLinear; + nd5->nodetype = EINDIRECT; + nd5->rtype = nd->rtype; + nd5->u.monadic = nd4; + IRO_AddToList(nd5, &list); + + nd6 = IRO_NewLinear(IROLinearOp2Arg); + *nd6 = *nd; + nd6->index = ++IRO_NumLinear; + nd6->u.diadic.left = list.tail; + nd6->next = NULL; + + nd7 = IRO_NewLinear(IROLinearOperand); + nd7->index = ++IRO_NumLinear; + nd7->rtype = pattern->ndC->rtype; + expr = IRO_NewENode(EINTCONST); + expr->rtype = pattern->ndC->rtype; + nd7->u.node = expr; + nd7->next = NULL; + expr->data.intval = pattern->val14; + + if ( + IS_LINEAR_DIADIC(nd, EANDASS) && + CInt64_Equal(pattern->val14, cint64_zero) + ) + { + nd6->nodetype = EASS; + } else if ( + IS_LINEAR_DIADIC(nd, EORASS) && + !CTool_EndianReadWord32(&pattern->val14.hi) + ) + { + UInt32 tmp = CInt64_GetULong(&pattern->val14); + if ( + (nd->rtype->size == 1 && tmp == 0xFF) || + (nd->rtype->size == 2 && tmp == 0xFFFF) || + (nd->rtype->size == 4 && tmp == 0xFFFFFFFF) + ) + { + nd6->nodetype = EASS; + } + } + + IRO_AddToList(nd7, &list); + + if (IS_LINEAR_MONADIC(pattern->nd10, ETYPCON)) { + nd8 = IRO_NewLinear(IROLinearOp1Arg); + *nd8 = *pattern->nd10; + nd8->index = ++IRO_NumLinear; + nd8->u.monadic = nd7; + nd8->next = NULL; + IRO_AddToList(nd8, &list); + } else { + nd8 = nd7; + } + nd6->u.diadic.right = nd8; + IRO_AddToList(nd6, &list); + + if (!firstnode) + firstnode = list.head; + } + + if (nd == lastnd) + break; + nd = nd->next; + } + + if (list.head && list.tail) + IRO_Paste(list.head, list.tail, fnode2->last); + } + } while (++pass < 8); } -static void PatternMatchLoop() { +static int PatternMatchLoop(IRONode *fnode, IROLoop *loop, IROLoopInd *ind, UInt32 *unrollFactor, SInt32 *result1, SInt32 *result2, LoopPattern *pattern) { + IROLinear *scan; + IROLinear *varnode; + IROLinear *nd1; + IROLinear *nd2; + IROLinear *left1; + IROLinear *left2; + IROLinear *right1; + IROLinear *right2; + Object *obj1; + Object *obj2; + CInt64 shl; + CInt64 val; + + *result1 = 0; + *result2 = 0; + + if ((scan = fnode->first)) { + while (1) { + if ( + (scan->index < loop->index20 || scan->index > loop->index24) && + !(scan->flags & IROLF_Reffed) && + scan->type != IROLinearNop && + scan->type != IROLinearLabel + ) + { + if (IS_LINEAR_DIADIC_3(scan, EORASS, EXORASS, EANDASS)) { + (*result2)++; + if (IS_LINEAR_MONADIC(scan->u.diadic.left, EINDIRECT)) { + varnode = scan->u.diadic.left->u.monadic; + if (IS_LINEAR_DIADIC(varnode, EADD)) { + pattern->nd4 = varnode->u.diadic.left; + pattern->type = varnode->rtype; + if (IRO_IsVariable(varnode->u.diadic.left)) { + pattern->nd0 = varnode->u.diadic.right; + if ( + IS_LINEAR_DIADIC(pattern->nd0, ESHL) && + IRO_IsConstant(pattern->nd0->u.diadic.right) + ) + { + pattern->val1C = pattern->nd0->u.diadic.right->u.node->data.intval; + nd1 = pattern->nd0->u.diadic.left; + } else { + return 0; + } + } else { + return 0; + } + } else { + return 0; + } + } else { + return 0; + } + + pattern->nd10 = scan->u.diadic.right; + + if (IS_LINEAR_MONADIC(pattern->nd10, ETYPCON)) { + if (IS_LINEAR_DIADIC(scan, EANDASS)) { + if (IS_LINEAR_MONADIC(pattern->nd10->u.monadic, EBINNOT)) { + pattern->ndC = pattern->nd10->u.monadic->u.monadic; + } else { + return 0; + } + } else { + pattern->ndC = pattern->nd10->u.monadic; + } + + if (IS_LINEAR_DIADIC(pattern->ndC, ESHL) && IRO_IsConstant(pattern->ndC->u.diadic.left)) { + val = pattern->ndC->u.diadic.left->u.node->data.intval; + nd2 = pattern->ndC->u.diadic.right; + } else { + return 0; + } + } else if (IS_LINEAR_DIADIC(pattern->nd10, ESHL) && IS_LINEAR_DIADIC_2(scan, EORASS, EXORASS)) { + pattern->ndC = pattern->nd10; + if (IRO_IsConstant(pattern->ndC->u.diadic.left)) { + val = pattern->ndC->u.diadic.left->u.node->data.intval; + nd2 = pattern->ndC->u.diadic.right; + } else { + return 0; + } + } else if (IS_LINEAR_MONADIC(pattern->nd10, EBINNOT) && IS_LINEAR_DIADIC(scan, EANDASS)) { + pattern->ndC = pattern->nd10->u.monadic; + if (IS_LINEAR_DIADIC(pattern->ndC, ESHL) && IRO_IsConstant(pattern->ndC->u.diadic.left)) { + val = pattern->ndC->u.diadic.left->u.node->data.intval; + nd2 = pattern->ndC->u.diadic.right; + } else { + return 0; + } + } else { + return 0; + } + + if (IS_LINEAR_DIADIC(nd2, EAND) && IS_LINEAR_DIADIC(nd1, ESHR)) { + left1 = nd1->u.diadic.left; + left2 = nd2->u.diadic.left; + obj1 = IRO_IsVariable(left1); + obj2 = IRO_IsVariable(left2); + if (obj1 == obj2 && obj1 == ind->var->object) { + right1 = nd1->u.diadic.right; + right2 = nd2->u.diadic.right; + if (IRO_IsConstant(right1) && IRO_IsConstant(right2)) { + shl = cint64_one; + shl = CInt64_Shl(shl, right1->u.node->data.intval); + shl = CInt64_Sub(shl, cint64_one); + if (CInt64_Equal(shl, right2->u.node->data.intval)) { + if (CTool_EndianReadWord32(&shl.hi) == 0) { + *unrollFactor = CInt64_GetULong(&shl) + 1; + if (CheckConstant(CInt64_Add(shl, cint64_one), val, &pattern->val14)) { + (*result1)++; + if (IS_LINEAR_DIADIC(scan, EANDASS)) + pattern->val14 = CInt64_Not(pattern->val14); + } + } else { + return 0; + } + } else { + return 0; + } + } else { + return 0; + } + } else { + return 0; + } + } else { + return 0; + } + } else { + return 0; + } + } + + if (scan == fnode->last) + break; + scan = scan->next; + } + } + + return 1; } -static void UnrollWhileLoop() { +static UInt32 UnrollWhileLoop(IRONode *header, IRONode *fnode2, IRONode *fnode3, IROLoop *loop, UInt32 unrollFactor) { + IROLoopInd *ind; + IRONode *scan; + CLabel *lastlabel; + IROLinear *lastlabelnode; + IROLinear *earlyLoopExitTest; + CLabel *earlyLoopExitTestLabel; + IROLinear *origIterationCount; + IROLinear *unrolledFinalValue; + IROLinear *preAlignTemp; + IROLinear *newFinalValue; + IROLinear *savedHead60; + IROLinear *unrolledBodyEntryTest; + CLabel *label; + IROLinear *savedHead2; + IROLinear *loophead25; + IROLinear *loopend; + IROLinear *loopscan; + IROLinear *indvar; + IROLinear *less; + IROLinear *loopExitTest; + IROLinear *saveTail; + CLabel *label2; + IROLinear *gotond; + CLabel *label3; + IROLinear *savedHead3; + IROLinear *updIndInc; + IROLinear *label2nd; + IROLinear *less2; + IROLinear *saveTail2; + IROLinear *less3; + IROLinear *wtf; + IROLinear *constnd; + IROLinear *ass; + IROLinear *nd18; + IRONode *fn19; + IRONode *newfnode1; + IRONode *newfnode2; + IRONode *newfnode3; + IRONode *newfnode4; + IRONode *newfnode5; + IRONode *newfnode6; + IRONode *newfnode7; + IRONode *newfnode8; + IROLinear *lastnd; + ENode *expr; + SInt32 result1; + SInt32 result2; + LoopPattern pattern; + IROList list; + + IRO_Dump("while(n--) loop \n"); + + if (loop->flags & LoopFlags_800) { + IRO_Dump("loop not unrolled because induction used in loop \n"); + return 0; + } + if (loop->flags & LoopFlags_1000) { + IRO_Dump("loop not unrolled because loop has multiple exits \n"); + return 0; + } + + if (!(loop->flags & LP_HAS_MULTIPLE_INDUCTIONS)) + return 0; + + for (ind = FirstInd; ind; ind = ind->next) { + if ((ind->flags & LoopInd_HasMod) && (ind->flags & LoopInd_HasDiv)) + break; + } + + if (!ind) { + IRO_Dump("Could not find loop with and induction with MOD and DIV operation\n"); + return 0; + } + + if (!IRO_IsUnsignedType(ind->nd->rtype)) + return 0; + + if (ind->nd->type == IROLinearOp2Arg) { + if (ind->nd->nodetype == EADDASS && IRO_IsConstant(ind->nd->u.diadic.right)) { + if (ind->addConst != 1) + return 0; + } else if (ind->nd->nodetype == EASS) { + if ( + ind->nd->u.diadic.right->type != IROLinearOp2Arg || + ind->nd->u.diadic.right->nodetype != EADD || + !IRO_IsConstant(ind->nd->u.diadic.right->u.diadic.right) + ) + return 0; + + if (ind->addConst != 1) + return 0; + } else { + return 0; + } + } else if (ind->nd->type == IROLinearOp1Arg && ind->nd->nodetype != EPREINC && ind->nd->nodetype != EPOSTINC) { + return 0; + } + + loop->induction = ind; + loop->index24 = ind->nd->index; + loop->index20 = IRO_FindStart(ind->nd)->index; + + scan = IRO_FirstNode; + memset(&pattern, 0, sizeof(pattern)); + while (scan) { + if (Bv_IsBitSet(scan->index, InLoop) && scan != header) { + if (!PatternMatchLoop(scan, loop, ind, &unrollFactor, &result1, &result2, &pattern)) + return 0; + } + scan = scan->nextnode; + } + + if (result1 > 1 || result2 > 1) + return 0; + + lastlabel = fnode2->last->u.label.label; + lastlabelnode = IRO_FindLabelNode(fnode2->last->u.label.label, fnode2->last); + + IRO_InitList(&list); + IRO_DuplicateExprRange(lastlabelnode->next, LoopNode->last->u.label.x4->u.diadic.left, &list); + IRO_DuplicateExpr(LoopNode->last->u.label.x4, &list); + IRO_Paste(list.head, list.tail, fnode2->last); + lastlabelnode = list.tail; + + IRO_InitList(&list); + earlyLoopExitTest = BuildEarlyLoopExitTest(LoopNode->last->type, &list); + earlyLoopExitTestLabel = IRO_NewLabel(); + earlyLoopExitTest->u.label.label = earlyLoopExitTestLabel; + earlyLoopExitTest->u.label.x4 = lastlabelnode; + earlyLoopExitTest->u.label.x4->flags |= IROLF_Reffed; + earlyLoopExitTest->rtype = LoopNode->last->rtype; + IRO_Paste(list.head, list.tail, fnode2->last); + + IRO_InitList(&list); + origIterationCount = BuildOrigIterationCount_DoWhile(&list, loop); + IRO_Paste(list.head, list.tail, fnode2->last); + savedHead60 = list.head; + + IRO_InitList(&list); + preAlignTemp = BuildPreAlignTemp(ind, unrollFactor, &list); + IRO_Paste(list.head, list.tail, fnode2->last); + + IRO_InitList(&list); + unrolledFinalValue = BuildUnrolledFinalvalue_DoWhile(origIterationCount, unrollFactor, &list, loop); + IRO_Paste(list.head, list.tail, fnode2->last); + + IRO_InitList(&list); + newFinalValue = BuildNewFinalvalue_DoWhile(origIterationCount, unrollFactor, &list, loop); + IRO_Paste(list.head, list.tail, fnode2->last); + + IRO_InitList(&list); + BuildUnrolledBodyEntryTest(&list, origIterationCount, unrollFactor, lastlabel); + IRO_Paste(list.head, list.tail, fnode2->last); + unrolledBodyEntryTest = list.tail; + + IRO_InitList(&list); + label = BuildLabel(&list); + IRO_Paste(list.head, list.tail, fnode2->last); + + savedHead2 = list.head; + loophead25 = NULL; + for (scan = fnode3; scan && scan != header; scan = scan->nextnode) { + IRO_InitList(&list); + loopend = scan->last; + loopscan = scan->first; + while (1) { + if (loopscan->stmt) + loopscan->stmt->flags |= StmtFlag_10; + if (loopscan->type != IROLinearLabel && !(loopscan->flags & IROLF_Reffed)) { + IRO_DuplicateExpr(loopscan, &list); + if (!loophead25) + loophead25 = list.head; + } + if (loopscan == loopend) + break; + loopscan = loopscan->next; + } + + if (list.head && list.tail) + IRO_Paste(list.head, list.tail, fnode2->last); + } + + IRO_InitList(&list); + + if (ind->nd->type == IROLinearOp1Arg) + IRO_DuplicateExpr(ind->nd->u.monadic, &list); + else + IRO_DuplicateExpr(ind->nd->u.diadic.left, &list); + list.tail->flags &= ~IROLF_Assigned; + indvar = list.tail; + + IRO_DuplicateExpr(preAlignTemp, &list); + list.tail->flags &= ~IROLF_Assigned; + + less = IRO_NewLinear(IROLinearOp2Arg); + less->nodetype = ELESS; + less->rtype = TYPE(&stbool); + less->index = ++IRO_NumLinear; + less->next = NULL; + less->u.diadic.left = indvar; + less->u.diadic.right = list.tail; + IRO_AddToList(less, &list); + less->flags |= IROLF_Reffed; + + loopExitTest = BuildLoopExitTest(LoopNode->last->type, &list); + loopExitTest->u.label.label = label; + loopExitTest->u.label.x4 = less; + loopExitTest->u.label.x4->flags |= IROLF_Reffed; + loopExitTest->rtype = LoopNode->last->rtype; + IRO_Paste(list.head, list.tail, fnode2->last); + saveTail = list.tail; + + IRO_InitList(&list); + label2 = IRO_NewLabel(); + gotond = IRO_NewLinear(IROLinearOp1Arg); + gotond->index = ++IRO_NumLinear; + gotond->type = IROLinearGoto; + gotond->u.label.label = label2; + IRO_AddToList(gotond, &list); + IRO_Paste(list.head, list.tail, fnode2->last); + + IRO_InitList(&list); + label3 = BuildLabel(&list); + IRO_Paste(list.head, list.tail, fnode2->last); + savedHead3 = list.head; + + UnrollWhileLoopBody(header, fnode2, fnode3, loop, &pattern, unrollFactor); + updIndInc = UpdateInductionIncrement(loop, 8 * unrollFactor, fnode2->last); + + IRO_InitList(&list); + label2nd = IRO_NewLinear(IROLinearLabel); + label2nd->index = IRO_NumLinear++; + label2nd->u.label.label = label2; + label2nd->flags |= IROLF_1; + IRO_AddToList(label2nd, &list); + IRO_Paste(list.head, list.tail, fnode2->last); + + IRO_InitList(&list); + + if (ind->nd->type == IROLinearOp1Arg) + IRO_DuplicateExpr(ind->nd->u.monadic, &list); + else + IRO_DuplicateExpr(ind->nd->u.diadic.left, &list); + list.tail->flags &= ~IROLF_Assigned; + indvar = list.tail; + + IRO_DuplicateExpr(unrolledFinalValue, &list); + list.tail->flags &= ~IROLF_Assigned; + + less2 = IRO_NewLinear(IROLinearOp2Arg); + less2->nodetype = ELESS; + less2->rtype = TYPE(&stbool); + less2->index = ++IRO_NumLinear; + less2->next = NULL; + less2->u.diadic.left = indvar; + less2->u.diadic.right = list.tail; + IRO_AddToList(less2, &list); + less2->flags |= IROLF_Reffed; + + loopExitTest = BuildLoopExitTest(LoopNode->last->type, &list); + loopExitTest->u.label.label = label3; + loopExitTest->u.label.x4 = less2; + loopExitTest->u.label.x4->flags |= IROLF_Reffed; + loopExitTest->rtype = LoopNode->last->rtype; + IRO_Paste(list.head, list.tail, fnode2->last); + saveTail2 = list.tail; + + IRO_InitList(&list); + + if (ind->nd->type == IROLinearOp1Arg) + IRO_DuplicateExpr(ind->nd->u.monadic, &list); + else + IRO_DuplicateExpr(ind->nd->u.diadic.left, &list); + list.tail->flags &= ~IROLF_Assigned; + indvar = list.tail; + + IRO_DuplicateExpr(newFinalValue, &list); + list.tail->flags &= ~IROLF_Assigned; + + less3 = IRO_NewLinear(IROLinearOp2Arg); + less3->nodetype = ELESS; + less3->rtype = TYPE(&stbool); + less3->index = ++IRO_NumLinear; + less3->next = NULL; + less3->u.diadic.left = indvar; + less3->u.diadic.right = list.tail; + IRO_AddToList(less3, &list); + less3->flags |= IROLF_Reffed; + + wtf = LoopNode->last->u.label.x4; + IRO_Paste(list.head, list.tail, LoopNode->last); + LoopNode->last->u.label.x4 = list.tail; + + IRO_InitList(&list); + + constnd = IRO_NewLinear(IROLinearOperand); + constnd->index = ++IRO_NumLinear; + expr = IRO_NewENode(EINTCONST); + expr->rtype = wtf->u.diadic.left->rtype; + expr->data.intval = cint64_zero; + constnd->u.node = expr; + constnd->rtype = expr->rtype; + IRO_AddToList(constnd, &list); + constnd->flags |= IROLF_Reffed; + + IRO_DuplicateExpr(wtf->u.diadic.left, &list); + + ass = IRO_NewLinear(IROLinearOp2Arg); + ass->nodetype = EASS; + ass->rtype = list.tail->rtype; + ass->index = ++IRO_NumLinear; + ass->next = NULL; + ass->u.diadic.left = list.tail; + ass->u.diadic.right = constnd; + IRO_AddToList(ass, &list); + ass->flags |= IROLF_Assigned; + + IRO_NopOut(wtf); + + fn19 = fnode2->nextnode; + nd18 = fnode2->last; + fnode2->last = earlyLoopExitTest; + + newfnode1 = IRO_NewFlowGraphNode(); + newfnode1->first = savedHead60; + newfnode1->last = unrolledBodyEntryTest; + fnode2->nextnode = newfnode1; + + newfnode2 = IRO_NewFlowGraphNode(); + newfnode2->first = savedHead2; + newfnode2->last = saveTail; + savedHead2->u.label.label->stmt = (Statement *) newfnode2; + newfnode1->nextnode = newfnode2; + + newfnode3 = IRO_NewFlowGraphNode(); + newfnode3->first = gotond; + newfnode3->last = gotond; + newfnode2->nextnode = newfnode3; + + newfnode4 = IRO_NewFlowGraphNode(); + newfnode4->first = savedHead3; + newfnode4->last = updIndInc; + savedHead3->u.label.label->stmt = (Statement *) newfnode4; + newfnode3->nextnode = newfnode4; + + newfnode5 = IRO_NewFlowGraphNode(); + newfnode5->first = label2nd; + newfnode5->last = saveTail2; + label2nd->u.label.label->stmt = (Statement *) newfnode5; + newfnode4->nextnode = newfnode5; + + newfnode6 = IRO_NewFlowGraphNode(); + newfnode6->first = nd18; + newfnode6->last = nd18; + newfnode5->nextnode = newfnode6; + newfnode6->nextnode = fn19; + + newfnode7 = oalloc(sizeof(IRONode)); + memset(newfnode7, 0, sizeof(IRONode)); + newfnode7->index = IRO_NumNodes; + IRO_NumNodes++; + + newfnode7->first = list.head; + newfnode7->last = list.tail; + + list.tail->next = LoopNode->last->next; + LoopNode->last->next = list.head; + + newfnode7->nextnode = LoopNode->nextnode; + LoopNode->nextnode = newfnode7; + + newfnode8 = oalloc(sizeof(IRONode)); + memset(newfnode8, 0, sizeof(IRONode)); + newfnode8->index = IRO_NumNodes; + IRO_NumNodes++; + + lastnd = IRO_NewLinear(IROLinearLabel); + lastnd->index = IRO_NumLinear++; + lastnd->next = NULL; + lastnd->u.label.label = earlyLoopExitTestLabel; + lastnd->flags |= IROLF_1; + earlyLoopExitTestLabel->stmt = (Statement *) newfnode8; + + newfnode8->first = lastnd; + newfnode8->last = lastnd; + + lastnd->next = newfnode7->last->next; + newfnode7->last->next = lastnd; + + newfnode8->nextnode = newfnode7->nextnode; + newfnode7->nextnode = newfnode8; + + return 1; } -void IRO_IterateForLoopBody() { +void IRO_IterateForLoopBody(IRONode *start, IRONode *end, IROLoop *loop, IROLinear *destnode, SInt32 addConst, CInt64 *val, Boolean funkyFlag) { + IROLinear *first = NULL; + IROLinear *last = NULL; + IRONode *fnode; + IROLinear *lastnd; + IROLinear *nd; + IROList list; + + for (fnode = start; fnode && fnode != end; fnode = fnode->nextnode) { + IRO_InitList(&list); + + lastnd = fnode->last; + nd = fnode->first; + while (1) { + if (nd->stmt) + nd->stmt->flags |= StmtFlag_10; + + if ( + (nd->index < loop->index20 || nd->index > loop->index24) && + nd->type != IROLinearLabel && + !(nd->flags & IROLF_Reffed) + ) + { + IRO_DuplicateExpr(nd, &list); + if (!first) + first = list.head; + last = list.tail; + } + + if (nd == lastnd) + break; + nd = nd->next; + } + + if (list.head && list.tail) + IRO_Paste(list.head, list.tail, destnode); + } + + if (funkyFlag) { + *val = CInt64_Add(*val, IRO_MakeLong(loop->induction->addConst)); + ChangeInductionReference(first, last, *val, loop); + } } -void IRO_LinearizeForLoopPostLoop() { +void IRO_LinearizeForLoopPostLoop(IRONode *fnode1, IRONode *fnode2, IROLoop *loop, IRONode *fnode3, UInt32 unrollFactor) { + IRONode *newfnode; + IROLinear *newnd; + SInt32 i; + CInt64 val; + + newfnode = oalloc(sizeof(IRONode)); + memset(newfnode, 0, sizeof(IRONode)); + newfnode->index = IRO_NumNodes; + IRO_NumNodes++; + + newnd = IRO_NewLinear(IROLinearNop); + newnd->index = IRO_NumLinear++; + newnd->next = NULL; + newnd->flags |= IROLF_1; + + newfnode->first = newfnode->last = newnd; + + newfnode->nextnode = fnode3->nextnode; + fnode3->nextnode = newfnode; + + newnd->next = fnode3->last->next; + fnode3->last->next = newnd; + + val = cint64_zero; + for (i = 0; i < unrollFactor; i++) + IRO_IterateForLoopBody(fnode2, fnode1, loop, newfnode->last, loop->induction->addConst, &val, i > 0); + UpdateInductionIncrement(loop, unrollFactor, newfnode->last); } -static void UnrollForLoop() { +static UInt32 UnrollForLoop(IRONode *header, IRONode *fnode2, IRONode *fnode3, IROLoop *loop, UInt32 unrollFactor) { + IROLinear *lastlabelnode; + IROLinear *earlyLoopExitTest; + IROLinear *origIterationCount; + IROLinear *saveHead1; + IROLinear *newFinalValue; + IROLinear *unrolledBodyEntryTest; + IROLinear *gotoNd; + IROLinear *saveHead2; + IROLinear *updIndInc; + IROLinear *labelNd; + IROLinear *saveTail2; + IROLinear *ndCopy; + IROLinear *saveTail3; + IROLinear *loopExitTest; + IROLinear *lastnd; + IROLinear *labelNd2; + IROLinear *saveTail4; + IROLinear *labelNd3; + IROLinear *scan; + IRONode *nd18; + IRONode *newfnode1; + IRONode *newfnode2; + IRONode *newfnode3; + IRONode *newfnode4; + IRONode *newfnode5; + IRONode *newfnode6; + CLabel *lastlabel; + CLabel *earlyLoopExitTestLabel; + CLabel *label; + CLabel *label2; + SInt32 i; + + IROList list; + CInt64 iterCount; + int isConstant; + UInt32 needOrigLoop = 0; + UInt32 needUnrollBodyTest = 0; + UInt32 resetUnrolledFinalValue = 0; + SInt32 leftOver; + CInt64 val; + + lastlabelnode = IRO_FindLabelNode(fnode2->last->u.label.label, fnode2->last); + lastlabel = IRO_NewLabel(); + + IRO_InitList(&list); + IRO_DuplicateExprRange(lastlabelnode->next, LoopNode->last->u.label.x4, &list); + IRO_DuplicateExpr(LoopNode->last->u.label.x4, &list); + IRO_Paste(list.head, list.tail, fnode2->last); + lastlabelnode = list.tail; + + IRO_InitList(&list); + earlyLoopExitTest = BuildEarlyLoopExitTest(LoopNode->last->type, &list); + earlyLoopExitTestLabel = IRO_NewLabel(); + earlyLoopExitTest->u.label.label = earlyLoopExitTestLabel; + earlyLoopExitTest->u.label.x4 = lastlabelnode; + earlyLoopExitTest->u.label.x4->flags |= IROLF_Reffed; + earlyLoopExitTest->rtype = LoopNode->last->rtype; + IRO_Paste(list.head, list.tail, fnode2->last); + + isConstant = IsIterationCountConstant(loop, &iterCount); + needOrigLoop = 1; + needUnrollBodyTest = 1; + resetUnrolledFinalValue = 0; + if (isConstant) + IRO_TestConstantIterationCount(loop, &iterCount, 1, &unrollFactor, &leftOver, &needOrigLoop, &needUnrollBodyTest, &resetUnrolledFinalValue); + + IRO_InitList(&list); + origIterationCount = BuildOrigIterationCount(&list, loop); + IRO_Paste(list.head, list.tail, fnode2->last); + saveHead1 = list.head; + + IRO_InitList(&list); + newFinalValue = BuildNewFinalvalue(origIterationCount, unrollFactor, &list, loop); + IRO_Paste(list.head, list.tail, fnode2->last); + + IRO_InitList(&list); + BuildUnrolledBodyEntryTest(&list, origIterationCount, unrollFactor, lastlabel); + IRO_Paste(list.head, list.tail, fnode2->last); + unrolledBodyEntryTest = list.tail; + + label = IRO_NewLabel(); + IRO_InitList(&list); + gotoNd = IRO_NewLinear(IROLinearOp1Arg); + gotoNd->index = ++IRO_NumLinear; + gotoNd->type = IROLinearGoto; + gotoNd->u.label.label = label; + IRO_AddToList(gotoNd, &list); + IRO_Paste(list.head, list.tail, fnode2->last); + + IRO_InitList(&list); + label2 = BuildLabel(&list); + IRO_Paste(list.head, list.tail, fnode2->last); + saveHead2 = list.head; + + val = cint64_zero; + for (i = 0; i < unrollFactor; i++) + IRO_IterateForLoopBody(fnode3, header, loop, fnode2->last, loop->induction->addConst, &val, i > 0); + updIndInc = UpdateInductionIncrement(loop, unrollFactor, fnode2->last); + + IRO_InitList(&list); + labelNd = IRO_NewLinear(IROLinearLabel); + labelNd->index = IRO_NumLinear++; + labelNd->u.label.label = label; + labelNd->flags |= IROLF_1; + IRO_AddToList(labelNd, &list); + IRO_Paste(list.head, list.tail, fnode2->last); + + IRO_InitList(&list); + + IRO_DuplicateExpr(LoopNode->last->u.label.x4->u.diadic.left, &list); + saveTail2 = list.tail; + + if (resetUnrolledFinalValue) + IRO_DuplicateExpr(loop->nd18->u.diadic.right, &list); + else + IRO_DuplicateExpr(newFinalValue, &list); + + ndCopy = IRO_NewLinear(LoopNode->last->u.label.x4->type); + *ndCopy = *LoopNode->last->u.label.x4; + ndCopy->index = ++IRO_NumLinear; + ndCopy->next = NULL; + ndCopy->expr = NULL; + ndCopy->u.diadic.left = saveTail2; + ndCopy->u.diadic.right = list.tail; + IRO_AddToList(ndCopy, &list); + + IRO_Paste(list.head, list.tail, fnode2->last); + saveTail3 = list.tail; + + IRO_InitList(&list); + loopExitTest = BuildLoopExitTest(LoopNode->last->type, &list); + loopExitTest->u.label.label = label2; + loopExitTest->u.label.x4 = saveTail3; + loopExitTest->u.label.x4->flags |= IROLF_Reffed; + loopExitTest->rtype = LoopNode->last->rtype; + IRO_Paste(list.head, list.tail, fnode2->last); + saveTail4 = list.tail; + + IRO_InitList(&list); + labelNd2 = IRO_NewLinear(IROLinearLabel); + labelNd2->index = IRO_NumLinear++; + labelNd2->u.label.label = lastlabel; + labelNd2->flags |= IROLF_1; + IRO_AddToList(labelNd2, &list); + IRO_Paste(list.head, list.tail, fnode2->last); + + lastnd = fnode2->last; + nd18 = fnode2->nextnode; + fnode2->last = earlyLoopExitTest; + + newfnode1 = IRO_NewFlowGraphNode(); + newfnode1->first = saveHead1; + newfnode1->last = unrolledBodyEntryTest; + fnode2->nextnode = newfnode1; + + newfnode2 = IRO_NewFlowGraphNode(); + newfnode2->first = gotoNd; + newfnode2->last = gotoNd; + newfnode1->nextnode = newfnode2; + + newfnode3 = IRO_NewFlowGraphNode(); + newfnode3->first = saveHead2; + newfnode3->last = updIndInc; + + saveHead2->u.label.label->stmt = (Statement *) newfnode3; + if (newfnode2) + newfnode2->nextnode = newfnode3; + else + newfnode1->nextnode = newfnode3; + + newfnode4 = IRO_NewFlowGraphNode(); + newfnode4->first = labelNd; + newfnode4->last = saveTail4; + labelNd->u.label.label->stmt = (Statement *) newfnode4; + newfnode3->nextnode = newfnode4; + + newfnode5 = IRO_NewFlowGraphNode(); + newfnode5->first = labelNd2; + newfnode5->last = lastnd; + newfnode4->nextnode = newfnode5; + newfnode5->nextnode = nd18; + + newfnode6 = oalloc(sizeof(IRONode)); + memset(newfnode6, 0, sizeof(IRONode)); + newfnode6->index = IRO_NumNodes; + IRO_NumNodes++; + + labelNd3 = IRO_NewLinear(IROLinearLabel); + labelNd3->index = IRO_NumLinear++; + labelNd3->next = NULL; + labelNd3->u.label.label = earlyLoopExitTestLabel; + labelNd3->flags |= IROLF_1; + earlyLoopExitTestLabel->stmt = (Statement *) newfnode6; + + newfnode6->first = labelNd3; + newfnode6->last = labelNd3; + + labelNd3->next = LoopNode->last->next; + LoopNode->last->next = labelNd3; + + newfnode6->nextnode = LoopNode->nextnode; + LoopNode->nextnode = newfnode6; + + if (!needOrigLoop) { + NoOpBlock(newfnode5); + NoOpBlock(header); + NoOpBlock(fnode3); + NoOpBlock(loop->induction->fnode); + IRO_NopOut(newfnode1->last->u.label.x4); + newfnode1->last->type = IROLinearNop; + } + + if (!needUnrollBodyTest) { + IRO_NopOut(earlyLoopExitTest->u.label.x4); + earlyLoopExitTest->type = IROLinearNop; + + IRO_NopOut(newfnode4->last->u.label.x4); + newfnode4->last->type = IROLinearNop; + + if (newfnode2) + newfnode2->last->type = IROLinearNop; + + for (scan = newfnode1->first; scan; scan = scan->next) { + if (!(scan->flags & IROLF_Reffed)) + IRO_NopOut(scan); + if (scan == newfnode1->last) + break; + } + } + + return 1; } -static void UnrollStandardLoop() { +static UInt32 UnrollStandardLoop(IRONode *header, IRONode *fnode2, IRONode *fnode3, int count) { + IROLoop *loop; + + ConditionalHeaderAtBottom = 1; + loop = ExtractLoopInfo(header); + loop->xC = fnode2; + loop->x10 = fnode3; + FindAssignmenttoInductionVar(loop, fnode2); + + if (!IsLoopUnrollable(loop)) { + IRO_Dump("LoopUnroll:loop with header %d not unrolled because IsLoopUnrollable failed\n", header->index); + return 0; + } + + if (loop->flags & LoopFlags_10000) + return UnrollWhileLoop(header, fnode2, fnode3, loop, count); + else + return UnrollForLoop(header, fnode2, fnode3, loop, count); } -static void LoopUnroll() { +static void LoopUnroll(int count, IRONode *header) { + VarRecord *var; + IRONode *tmp; + UInt16 i; + UInt16 j; + IRONode *prevpred; + IRONode *prevsucc; + int foundpred; + UInt32 predcount; + UInt32 success = 0; + + LoopNode = header; + FindMustReach(); + + for (var = IRO_FirstVar; var; var = var->next) + var->xA = 1; + + ComputeLoopKills(); + ComputeLoopInvariance(); + ComputeLoopInduction(); + + LoopNode = header; + ConditionalHeaderAtBottom = 0; + + prevpred = NULL; + foundpred = 0; + for (i = 0; i < LoopNode->numpred; i++) { + tmp = IRO_NodeTable[LoopNode->pred[i]]; + if (!Bv_IsBitSet(tmp->index, InLoop)) { + foundpred = 1; + if (tmp->nextnode == header) { + CError_ASSERT(2101, !prevpred || tmp == prevpred); + prevpred = tmp; + } + } + } + + if (!foundpred) { + IRO_Dump("No predecessor outside the loop\n"); + return; + } + + if (LoopNode->last->type == IROLinearIf || LoopNode->last->type == IROLinearIfNot) { + if (LoopNode->nextnode && !Bv_IsBitSet(LoopNode->nextnode->index, InLoop)) { + prevsucc = NULL; + for (i = 0; i < LoopNode->numsucc; i++) { + tmp = IRO_NodeTable[LoopNode->succ[i]]; + if (Bv_IsBitSet(tmp->index, InLoop)) { + CError_ASSERT(2159, !prevsucc); + prevsucc = tmp; + } + } + + prevpred = NULL; + predcount = 0; + for (j = 0; j < LoopNode->numpred; j++) { + tmp = IRO_NodeTable[LoopNode->pred[j]]; + if (!Bv_IsBitSet(tmp->index, InLoop)) { + prevpred = tmp; + predcount++; + } + } + + if ( + predcount == 1 && + prevpred->last->type == IROLinearGoto && + prevpred->nextnode == prevsucc && + prevsucc != LoopNode + ) + { + success = UnrollStandardLoop(header, prevpred, prevsucc, count); + } + } + } else { + IRO_Dump(" LoopUnroll:Loop with header = %d is not a conditional loop\n", header->index); + } + + if (!success) + return; + + IRO_NodeTable = oalloc(sizeof(IRONode *) * IRO_NumNodes); + memset(IRO_NodeTable, 0, sizeof(IRONode *) * IRO_NumNodes); + for (tmp = IRO_FirstNode; tmp; tmp = tmp->nextnode) + IRO_NodeTable[tmp->index] = tmp; + IRO_ComputeSuccPred(); + IRO_ComputeDom(); + if (success) + IRO_Dump(" LoopUnroll:Loop with header = %d Unrolled\n", header->index); } -static void IsLoopUnrollable() { +static int IsLoopUnrollable(IROLoop *loop) { + CInt64 tmp; + + if (loop->flags & LP_LOOP_HAS_ASM) { + IRO_Dump("IsLoopUnrollable:No due to LP_LOOP_HAS_ASM \n"); + return 0; + } + if (loop->flags & LP_IFEXPR_NON_CANONICAL) { + IRO_Dump("IsLoopUnrollable:No due to LP_IFEXPR_NON_CANONICAL \n"); + return 0; + } + if (loop->flags & LP_LOOP_HAS_CALLS) { + IRO_Dump("IsLoopUnrollable:No due to LP_LOOP_HAS_CALLS \n"); + return 0; + } + if (loop->flags & LP_LOOP_HAS_CNTRLFLOW) { + IRO_Dump("IsLoopUnrollable:No due to LP_LOOP_HAS_CNTRLFLOW \n"); + return 0; + } + if (loop->flags & LP_INDUCTION_NOT_FOUND) { + IRO_Dump("IsLoopUnrollable:No due to LP_INDUCTION_NOT_FOUND \n"); + return 0; + } + if (loop->flags & LP_LOOP_HDR_HAS_SIDEEFFECTS) { + IRO_Dump("IsLoopUnrollable:No due to LP_LOOP_HDR_HAS_SIDEEFFECTS \n"); + return 0; + } + if (!(loop->flags & LoopFlags_200)) { + IRO_Dump("IsLoopUnrollable:No because header does not follow induction update \n"); + return 0; + } + + if (!(loop->flags & LoopFlags_10000)) { + IROLinear *upperBound = loop->nd18->u.diadic.right; + if (!IRO_IsIntConstant(upperBound) && !(upperBound->flags & IROLF_LoopInvariant)) { + IRO_Dump("IsLoopUnrollable:No because Loop Upper Bound is Variant in the loop\n"); + return 0; + } + if (!loop->nd14) { + IRO_Dump("IsLoopUnrollable:No because there is no initialization of loop index in PreHeader\n"); + return 0; + } + if (!IRO_IsVariable(loop->nd14->u.diadic.left)) { + IRO_Dump("IsLoopUnrollable:No because initial value of induction stored thru pointer\n"); + return 0; + } + + if (!IRO_IsUnsignedType(loop->nd14->rtype)) { + if (IRO_IsIntConstant(loop->nd14->u.diadic.right)) { + if (!CInt64_GreaterEqual(loop->nd14->u.diadic.right->u.node->data.intval, cint64_zero)) { + IRO_Dump("IsLoopUnrollable:No because initial value of induction is signed but init < 0\n"); + return 0; + } + } else if (IsIterationCountConstant(loop, &tmp)) { + IRO_Dump("IsLoopUnrollable:Yes, the limits substract out to be constants\n"); + } else { + IRO_Dump("IsLoopUnrollable:No because initial value of induction is signed and not constant\n"); + return 0; + } + } + + if (!(loop->flags & LP_LOOP_STEP_ISADD)) { + IRO_Dump("IsLoopUnrollable:No because LP_LOOP_STEP_ISADD is not set i.e induciton is not updated by 1\n"); + return 0; + } + + } else { + if (!IRO_IsUnsignedType(loop->nd18->u.diadic.left->rtype)) { + IRO_Dump("IsLoopUnrollable:No because the while loop induction is signed\n"); + return 0; + } + if (!(loop->flags & LoopFlags_2000)) { + IRO_Dump("IsLoopUnrollable:No because the while loop operator is not of decrement form\n"); + return 0; + } + } + + if (loop->sizeBySomeMeasurement > copts.loop_unroll_size_threshold) { + IRO_Dump("IsLoopUnrollable:No because loop size greater than threshold\n"); + return 0; + } + + return 1; } -void BuildEarlyLoopExitTest() { +IROLinear *BuildEarlyLoopExitTest(IROLinearType type, IROList *list) { + IROLinear *nd = IRO_NewLinear(IROLinearOp1Arg); + nd->index = ++IRO_NumLinear; + if (type == IROLinearIf) + nd->type = IROLinearIfNot; + else + nd->type = IROLinearIf; + IRO_AddToList(nd, list); + return nd; } -void BuildLoopExitTest() { +IROLinear *BuildLoopExitTest(IROLinearType type, IROList *list) { + IROLinear *nd = IRO_NewLinear(IROLinearOp1Arg); + nd->index = ++IRO_NumLinear; + nd->type = type; + IRO_AddToList(nd, list); + return nd; } -void IsIterationCountConstant() { +int IsIterationCountConstant(IROLoop *loop, CInt64 *pval) { + IROLinear *lowerBound; + IROLinear *upperBound; + Type *type; + int isUnsigned; + IROAddrRecord *lowerRec; + IROAddrRecord *upperRec; + CInt64 lowerval; + CInt64 upperval; + CInt64 incval; + CInt64 negOne; + + lowerBound = loop->nd14->u.diadic.right; + if (loop->flags & LoopFlags_1) { + upperBound = loop->nd18->u.diadic.right; + type = loop->nd18->u.diadic.right->rtype; + } else { + upperBound = loop->nd18->u.diadic.left; + type = loop->nd18->u.diadic.left->rtype; + } + + isUnsigned = IRO_IsUnsignedType(type); + + if (IRO_IsIntConstant(lowerBound) && IRO_IsIntConstant(upperBound)) { + lowerval = lowerBound->u.node->data.intval; + upperval = upperBound->u.node->data.intval; + if (isUnsigned) { + if (CInt64_LessEqualU(upperval, lowerval)) + return 0; + } else { + if (CInt64_LessEqual(upperval, lowerval)) + return 0; + } + + CInt64_SetLong(&incval, loop->induction->addConst); + CInt64_SetLong(&negOne, -1); + *pval = CInt64_Sub(upperval, lowerval); + *pval = CInt64_Add(*pval, incval); + + if (IS_LINEAR_DIADIC(loop->nd18, ELESS)) + *pval = CInt64_Add(*pval, negOne); + + CError_ASSERT(2486, !CInt64_IsZero(&incval)); + + if (isUnsigned) + *pval = CInt64_DivU(*pval, incval); + else + *pval = CInt64_Div(*pval, incval); + + if (CInt64_Equal(*pval, cint64_zero)) + return 0; + + if (isUnsigned) { + CError_ASSERT(2508, !CInt64_LessEqualU(*pval, cint64_zero)); + } else { + CError_ASSERT(2517, !CInt64_LessEqual(*pval, cint64_zero)); + } + + return 1; + } + + lowerRec = IRO_InitAddrRecordPointer(lowerBound); + upperRec = IRO_InitAddrRecordPointer(upperBound); + + if (IS_LINEAR_DIADIC(lowerBound, EADD)) { + IRO_DecomposeAddressExpression(lowerBound, lowerRec); + } else if (IRO_IsIntConstant(lowerBound)) { + lowerRec->numInts++; + IRO_AddElmToList(lowerBound, &lowerRec->ints); + lowerRec->numObjRefs = 0; + lowerRec->numMisc = 0; + } else { + lowerRec->numMisc++; + IRO_AddElmToList(lowerBound, &lowerRec->misc); + lowerRec->numObjRefs = 0; + lowerRec->numInts = 0; + } + + if (IS_LINEAR_DIADIC(upperBound, EADD)) { + IRO_DecomposeAddressExpression(upperBound, upperRec); + } else if (IRO_IsIntConstant(upperBound)) { + upperRec->numInts++; + IRO_AddElmToList(upperBound, &upperRec->ints); + upperRec->numObjRefs = 0; + upperRec->numMisc = 0; + } else { + upperRec->numMisc++; + IRO_AddElmToList(upperBound, &upperRec->misc); + upperRec->numObjRefs = 0; + upperRec->numInts = 0; + } + + if (IsDifferenceOfTermsConstant(lowerRec, upperRec, isUnsigned, pval)) { + if (IS_LINEAR_DIADIC(loop->nd18, ELESSEQU)) + *pval = CInt64_Add(*pval, cint64_one); + return 1; + } + + return 0; } -static void IsDifferenceOfTermsConstant() { +static int IsDifferenceOfTermsConstant(IROAddrRecord *lowerRec, IROAddrRecord *upperRec, int isUnsigned, CInt64 *pval) { + UInt32 i; + CInt64 upperval; + CInt64 lowerval; + IROElmList *el; + IROLinear *nd; + + if (upperRec->numObjRefs == lowerRec->numObjRefs && upperRec->numObjRefs != 0) + return 0; + else if (upperRec->numObjRefs != lowerRec->numObjRefs) + return 0; + + if (upperRec->numMisc == lowerRec->numMisc && upperRec->numMisc != 0) { + for (i = 0; i < upperRec->numMisc; i++) { + // bug? surely this should index on i...? + if (!IRO_ExprsSame(lowerRec->misc->element, upperRec->misc->element)) + return 0; + } + } else if (upperRec->numMisc != lowerRec->numMisc) { + return 0; + } + + upperval = cint64_zero; + for (el = upperRec->ints; el; el = el->next) { + nd = el->element; + upperval = CMach_CalcIntDiadic(nd->rtype, upperval, '+', nd->u.node->data.intval); + } + + lowerval = cint64_zero; + for (el = lowerRec->ints; el; el = el->next) { + nd = el->element; + lowerval = CMach_CalcIntDiadic(nd->rtype, lowerval, '+', nd->u.node->data.intval); + } + + if (CInt64_Equal(upperval, lowerval)) + return 0; + + if (CInt64_Greater(upperval, lowerval)) { + *pval = CInt64_Sub(upperval, lowerval); + return 1; + } else { + return 0; + } } -void NoOpBlock() { +void NoOpBlock(IRONode *fnode) { + IROLinear *last, *scan; + + for (scan = fnode->first, last = fnode->last; scan; scan = scan->next) { + scan->type = IROLinearNop; + if (scan == last) + break; + } } -void IRO_TestConstantIterationCount() { +void IRO_TestConstantIterationCount(IROLoop *loop, CInt64 *iterCount, SInt32 vectorStride, UInt32 *unrollFactor, SInt32 *leftOver, UInt32 *needOrigLoop, UInt32 *needUnrollBodyTest, UInt32 *resetUnrolledFinalValue) { + UInt32 isUnsigned; + CInt64 val; + CInt64 val3; + CInt64 mod; + CInt64 val2; + CInt64 loopvar3; + CInt64 loopvar1; + CInt64 loopvar2; + CInt64 strideVal; + + CError_ASSERT(2737, *unrollFactor); + + isUnsigned = IRO_IsUnsignedType( + (loop->flags & LoopFlags_1) ? loop->nd18->u.diadic.right->rtype :loop->nd18->u.diadic.left->rtype); + + CError_ASSERT(2756, vectorStride); + + strideVal = IRO_MakeLong(vectorStride); + if (isUnsigned ? CInt64_LessU(*iterCount, strideVal) : CInt64_Less(*iterCount, strideVal)) { + *needOrigLoop = 1; + *needUnrollBodyTest = 0; + *unrollFactor = 0; + *leftOver = CInt64_GetULong(iterCount); + } else { + switch (vectorStride) { + case 1: + val = *iterCount; + break; + case 2: + val = CInt64_ShrU(*iterCount, cint64_one); + break; + case 4: + val = CInt64_ShrU(*iterCount, IRO_MakeLong(2)); + break; + case 8: + val = CInt64_ShrU(*iterCount, IRO_MakeLong(3)); + break; + case 16: + val = CInt64_ShrU(*iterCount, IRO_MakeLong(4)); + break; + default: + val = CInt64_Div(*iterCount, strideVal); + } + + if (CInt64_LessU(val, IRO_MakeLong(*unrollFactor))) + *unrollFactor = CInt64_GetULong(&val); + + CInt64_SetLong(&val2, *unrollFactor); + switch (vectorStride) { + case 1: + val3 = cint64_zero; + break; + case 2: + val3 = CInt64_And(*iterCount, cint64_one); + break; + case 4: + val3 = CInt64_And(*iterCount, IRO_MakeLong(3)); + break; + case 8: + val3 = CInt64_And(*iterCount, IRO_MakeLong(7)); + break; + case 16: + val3 = CInt64_And(*iterCount, IRO_MakeLong(15)); + break; + default: + val3 = CInt64_Mod(*iterCount, strideVal); + } + + if (CInt64_LessEqualU(val, IRO_MakeLong(8))) { + *needUnrollBodyTest = vectorStride > 1; + *unrollFactor = CInt64_GetULong(&val); + *leftOver = CInt64_GetULong(&val3); + *needOrigLoop = *leftOver != 0; + *resetUnrolledFinalValue = !(*needOrigLoop && *needUnrollBodyTest); + } else { + loopvar1 = IRO_MakeLong(0x7FFFFFFF); + loopvar2 = IRO_MakeLong(0x7FFFFFFF); + do { + mod = CInt64_Mod(val, val2); + loopvar3 = CInt64_Add(CInt64_Mul(mod, strideVal), val3); + if (CInt64_Less(loopvar3, loopvar2)) { + loopvar2 = loopvar3; + loopvar1 = val2; + } + if (vectorStride > 1) + break; + val2 = CInt64_Add(val2, cint64_negone); + } while (CInt64_GreaterEqualU(CInt64_Mul(val2, val2), val)); + + *unrollFactor = CInt64_GetULong(&loopvar1); + *leftOver = CInt64_GetULong(&loopvar2); + *needOrigLoop = *leftOver != 0; + *needUnrollBodyTest = CInt64_Less(loopvar1, val) || vectorStride > 1; + *resetUnrolledFinalValue = !(*needOrigLoop && *needUnrollBodyTest); + } + } + + IRO_Dump( + "---- IterCount = %d, VectorStride = %d, UnrollFactor = %d, LeftOver = %d,\n" + "\tNeedOrigLoop = %d, NeedUnrollBodyTest = %d, ResetUnrolledFinalValue = %d\n", + CInt64_GetULong(iterCount), vectorStride, *unrollFactor, *leftOver, + *needOrigLoop, *needUnrollBodyTest, *resetUnrolledFinalValue + ); } -void BuildOrigIterationCount() { +IROLinear *BuildOrigIterationCount(IROList *list, IROLoop *loop) { + IROLinear *upperBound; + IROLinear *nd29b; + IROLinear *lowerBound; + IROLinear *finalCount; + IROLinear *divisor; + Type *type; + IROLinear *nd25; + IROLinear *tmp; + Boolean isZeroBase; + Object *tempobj; + IROLinear *iterCount; + IROLinear *negone; + IROLinear *ass; + ENode *expr; + SInt32 powval; + + isZeroBase = 0; + lowerBound = loop->nd14->u.diadic.right; + if (IRO_IsIntConstant(lowerBound) && CInt64_Equal(lowerBound->u.node->data.intval, cint64_zero)) + isZeroBase = 1; + + if (!isZeroBase) + lowerBound = IRO_DuplicateExpr(lowerBound, list); + + if (loop->flags & LoopFlags_1) { + upperBound = IRO_DuplicateExpr(loop->nd18->u.diadic.right, list); + type = loop->nd18->u.diadic.right->rtype; + } else { + upperBound = IRO_DuplicateExpr(loop->nd18->u.diadic.left, list); + type = loop->nd18->u.diadic.left->rtype; + } + + CError_ASSERT(2924, loop->induction); + CError_ASSERT(2929, loop->induction->addConst); + + divisor = IRO_NewLinear(IROLinearOperand); + divisor->index = ++IRO_NumLinear; + divisor->rtype = type; + expr = IRO_NewENode(EINTCONST); + expr->rtype = type; + CInt64_SetLong(&expr->data.intval, loop->induction->addConst); + divisor->u.node = expr; + + if (isZeroBase) { + iterCount = upperBound; + } else { + iterCount = IRO_NewLinear(IROLinearOp2Arg); + iterCount->index = ++IRO_NumLinear; + iterCount->nodetype = ESUB; + iterCount->u.diadic.left = upperBound; + iterCount->u.diadic.right = lowerBound; + iterCount->rtype = type; + IRO_AddToList(iterCount, list); + } + + nd25 = IRO_DuplicateExpr(divisor, list); + + nd29b = IRO_NewLinear(IROLinearOp2Arg); + nd29b->index = ++IRO_NumLinear; + nd29b->nodetype = EADD; + nd29b->u.diadic.left = iterCount; + nd29b->u.diadic.right = nd25; + nd29b->rtype = type; + IRO_AddToList(nd29b, list); + + if (loop->nd18->type == IROLinearOp2Arg && loop->nd18->nodetype == ELESS) { + tmp = nd29b; + + negone = IRO_NewLinear(IROLinearOperand); + negone->index = ++IRO_NumLinear; + negone->rtype = type; + expr = IRO_NewENode(EINTCONST); + expr->rtype = type; + CInt64_SetLong(&expr->data.intval, -1); + negone->u.node = expr; + IRO_AddToList(negone, list); + + nd29b = IRO_NewLinear(IROLinearOp2Arg); + nd29b->index = ++IRO_NumLinear; + nd29b->nodetype = EADD; + nd29b->u.diadic.left = tmp; + nd29b->u.diadic.right = negone; + nd29b->rtype = type; + IRO_AddToList(nd29b, list); + } + + if (CInt64_Equal(divisor->u.node->data.intval, cint64_one)) { + finalCount = nd29b; + } else { + if (divisor->rtype->size <= 4 && IS_TYPE_INT(divisor->rtype) && IRO_IsPow2(divisor, &powval)) { + finalCount = IRO_NewLinear(IROLinearOp2Arg); + finalCount->index = ++IRO_NumLinear; + finalCount->nodetype = ESHL; + finalCount->u.diadic.left = nd29b; + finalCount->u.diadic.right = divisor; + CInt64_SetLong(&divisor->u.node->data.intval, powval); + finalCount->rtype = type; + IRO_AddToList(divisor, list); + IRO_AddToList(finalCount, list); + } else { + finalCount = IRO_NewLinear(IROLinearOp2Arg); + finalCount->index = ++IRO_NumLinear; + finalCount->nodetype = EDIV; + finalCount->u.diadic.left = nd29b; + finalCount->u.diadic.right = divisor; + finalCount->rtype = type; + IRO_AddToList(divisor, list); + IRO_AddToList(finalCount, list); + } + } + + tempobj = create_temp_object(type); + IRO_FindVar(tempobj, 1, 1); + + ass = IRO_NewLinear(IROLinearOp2Arg); + ass->index = ++IRO_NumLinear; + ass->nodetype = EASS; + ass->u.diadic.left = IRO_TempReference(tempobj, list); + ass->u.diadic.left->flags |= IROLF_Assigned | IROLF_Ind; + ass->u.diadic.left->u.monadic->flags |= IROLF_Assigned | IROLF_Ind; + ass->u.diadic.right = finalCount; + ass->u.diadic.right->flags |= IROLF_Reffed; + ass->rtype = type; + IRO_AddToList(ass, list); + + return ass->u.diadic.left; } -static void BuildOrigIterationCount_DoWhile() { +static IROLinear *BuildOrigIterationCount_DoWhile(IROList *list, IROLoop *loop) { + IROLinear *finalCount; + IROLinear *count; + IROLinear *ass; + Type *type; + Object *tempobj; + ENode *expr; + + type = loop->nd18->u.diadic.left->rtype; + + count = IRO_NewLinear(IROLinearOperand); + count->index = ++IRO_NumLinear; + expr = IRO_NewENode(EINTCONST); + expr->rtype = type; + expr->data.intval = cint64_one; + count->u.node = expr; + count->rtype = type; + IRO_AddToList(count, list); + count->flags |= IROLF_Reffed; + + finalCount = IRO_NewLinear(IROLinearOp2Arg); + finalCount->index = ++IRO_NumLinear; + finalCount->nodetype = EADD; + finalCount->rtype = type; + finalCount->u.diadic.left = IRO_DuplicateExpr(loop->nd18->u.diadic.left, list); + finalCount->u.diadic.left->flags |= IROLF_Reffed; + finalCount->u.diadic.left->flags &= ~IROLF_Assigned; + finalCount->u.diadic.left->u.monadic->flags &= ~IROLF_Assigned; + finalCount->u.diadic.right = count; + IRO_AddToList(finalCount, list); + + tempobj = create_temp_object(type); + IRO_FindVar(tempobj, 1, 1); + + ass = IRO_NewLinear(IROLinearOp2Arg); + ass->index = ++IRO_NumLinear; + ass->nodetype = EASS; + ass->u.diadic.left = IRO_TempReference(tempobj, list); + ass->u.diadic.left->flags |= IROLF_Assigned | IROLF_Ind; + ass->u.diadic.left->u.monadic->flags |= IROLF_Assigned | IROLF_Ind; + ass->u.diadic.right = finalCount; + ass->rtype = type; + IRO_AddToList(ass, list); + + return ass->u.diadic.left; } -void BuildNewFinalvalue() { +IROLinear *BuildNewFinalvalue(IROLinear *iterCount, UInt32 unrollFactor, IROList *list, IROLoop *loop) { + IROLinear *sub; + IROLinear *addvalue; + Type *type; + IROLinear *ass; + IROLinear *dupbound; + Object *tempobj; + ENode *expr; + + type = iterCount->rtype; + + addvalue = IRO_NewLinear(IROLinearOperand); + addvalue->index = ++IRO_NumLinear; + addvalue->rtype = type; + expr = IRO_NewENode(EINTCONST); + expr->rtype = type; + CInt64_SetLong(&expr->data.intval, loop->induction->addConst * unrollFactor); + addvalue->u.node = expr; + IRO_AddToList(addvalue, list); + + if (loop->flags & LoopFlags_1) + dupbound = IRO_DuplicateExpr(loop->nd18->u.diadic.right, list); + else + dupbound = IRO_DuplicateExpr(loop->nd18->u.diadic.left, list); + + sub = IRO_NewLinear(IROLinearOp2Arg); + sub->index = ++IRO_NumLinear; + sub->nodetype = ESUB; + sub->u.diadic.left = dupbound; + sub->u.diadic.right = addvalue; + sub->rtype = type; + IRO_AddToList(sub, list); + + tempobj = create_temp_object(type); + IRO_FindVar(tempobj, 1, 1); + + ass = IRO_NewLinear(IROLinearOp2Arg); + ass->index = ++IRO_NumLinear; + ass->nodetype = EASS; + ass->u.diadic.left = IRO_TempReference(tempobj, list); + ass->u.diadic.left->flags |= IROLF_Assigned | IROLF_Ind; + ass->u.diadic.left->u.monadic->flags |= IROLF_Assigned | IROLF_Ind; + ass->u.diadic.right = sub; + ass->u.diadic.right->flags |= IROLF_Reffed; + ass->rtype = type; + IRO_AddToList(ass, list); + + return ass->u.diadic.left; } -static void BuildPreAlignTemp() { +static IROLinear *BuildPreAlignTemp(IROLoopInd *ind, UInt32 unrollFactor, IROList *list) { + Type *type; + IROLinear *indnd; + IROLinear *factornd; + IROLinear *div; + IROLinear *constnd; + IROLinear *add; + IROLinear *mul; + IROLinear *ass; + Object *tempobj; + ENode *expr; + + indnd = ind->nd; + type = indnd->rtype; + + factornd = IRO_NewLinear(IROLinearOperand); + factornd->index = ++IRO_NumLinear; + factornd->rtype = type; + expr = IRO_NewENode(EINTCONST); + expr->rtype = type; + CInt64_SetLong(&expr->data.intval, unrollFactor); + factornd->u.node = expr; + IRO_AddToList(factornd, list); + + if (indnd->type == IROLinearOp1Arg) + IRO_DuplicateExpr(indnd->u.monadic, list); + else + IRO_DuplicateExpr(indnd->u.diadic.left, list); + + list->tail->flags &= ~IROLF_Assigned; + list->tail->u.monadic->flags &= ~IROLF_Assigned; + + div = IRO_NewLinear(IROLinearOp2Arg); + div->index = ++IRO_NumLinear; + div->nodetype = EDIV; + div->u.diadic.left = list->tail; + div->u.diadic.right = factornd; + div->rtype = type; + IRO_AddToList(div, list); + div->flags |= IROLF_Reffed; + + constnd = IRO_NewLinear(IROLinearOperand); + constnd->index = ++IRO_NumLinear; + expr = IRO_NewENode(EINTCONST); + expr->rtype = type; + expr->data.intval = cint64_one; + constnd->u.node = expr; + constnd->rtype = type; + IRO_AddToList(constnd, list); + constnd->flags |= IROLF_Reffed; + + add = IRO_NewLinear(IROLinearOp2Arg); + add->index = ++IRO_NumLinear; + add->nodetype = EADD; + add->u.diadic.left = div; + add->u.diadic.right = constnd; + add->rtype = type; + IRO_AddToList(add, list); + add->flags |= IROLF_Reffed; + + IRO_DuplicateExpr(factornd, list); + + mul = IRO_NewLinear(IROLinearOp2Arg); + mul->index = ++IRO_NumLinear; + mul->nodetype = EMUL; + mul->u.diadic.left = add; + mul->u.diadic.right = list->tail; + mul->rtype = type; + IRO_AddToList(mul, list); + mul->flags |= IROLF_Reffed; + + tempobj = create_temp_object(type); + IRO_FindVar(tempobj, 1, 1); + + ass = IRO_NewLinear(IROLinearOp2Arg); + ass->index = ++IRO_NumLinear; + ass->nodetype = EASS; + ass->u.diadic.left = IRO_TempReference(tempobj, list); + ass->u.diadic.left->flags |= IROLF_Assigned | IROLF_Ind; + ass->u.diadic.left->u.monadic->flags |= IROLF_Assigned | IROLF_Ind; + ass->u.diadic.right = mul; + ass->u.diadic.right->flags |= IROLF_Reffed; + ass->rtype = type; + IRO_AddToList(ass, list); + + return ass->u.diadic.left; } -static void BuildNewFinalvalue_DoWhile() { +static IROLinear *BuildNewFinalvalue_DoWhile(IROLinear *iterCount, UInt32 unrollFactor, IROList *list, IROLoop *loop) { + IROLinear *addvalue; + IROLinear *add; + IROLinear *mul; + IROLinear *ass; + Type *type; + Object *tempobj; + ENode *expr; + + type = iterCount->rtype; + + addvalue = IRO_NewLinear(IROLinearOperand); + addvalue->index = ++IRO_NumLinear; + addvalue->rtype = type; + expr = IRO_NewENode(EINTCONST); + expr->rtype = type; + CInt64_SetLong(&expr->data.intval, loop->induction->addConst); + addvalue->u.node = expr; + IRO_AddToList(addvalue, list); + addvalue->flags |= IROLF_Reffed; + + mul = IRO_NewLinear(IROLinearOp2Arg); + mul->index = ++IRO_NumLinear; + mul->nodetype = EMUL; + mul->u.diadic.left = IRO_DuplicateExpr(iterCount, list); + mul->u.diadic.right = addvalue; + mul->rtype = type; + IRO_AddToList(mul, list); + mul->flags |= IROLF_Reffed; + mul->u.diadic.left->flags &= ~IROLF_Assigned; + mul->u.diadic.left->u.diadic.left->flags &= ~IROLF_Assigned; + + if (loop->induction->nd->type == IROLinearOp1Arg) + IRO_DuplicateExpr(loop->induction->nd->u.monadic, list); + else + IRO_DuplicateExpr(loop->induction->nd->u.diadic.left, list); + list->tail->flags &= ~IROLF_Assigned; + list->tail->u.diadic.left->flags &= ~IROLF_Assigned; + + add = IRO_NewLinear(IROLinearOp2Arg); + add->index = ++IRO_NumLinear; + add->nodetype = EADD; + add->u.diadic.left = mul; + add->u.diadic.right = list->tail; + add->rtype = type; + IRO_AddToList(add, list); + add->flags |= IROLF_Reffed; + + tempobj = create_temp_object(type); + IRO_FindVar(tempobj, 1, 1); + + ass = IRO_NewLinear(IROLinearOp2Arg); + ass->index = ++IRO_NumLinear; + ass->nodetype = EASS; + ass->u.diadic.left = IRO_TempReference(tempobj, list); + ass->u.diadic.left->flags |= IROLF_Assigned | IROLF_Ind; + ass->u.diadic.left->u.monadic->flags |= IROLF_Assigned | IROLF_Ind; + ass->u.diadic.right = add; + ass->u.diadic.right->flags |= IROLF_Reffed; + ass->rtype = type; + IRO_AddToList(ass, list); + + return ass->u.diadic.left; } -static void BuildUnrolledFinalvalue_DoWhile() { +static IROLinear *BuildUnrolledFinalvalue_DoWhile(IROLinear *iterCount, UInt32 unrollFactor, IROList *list, IROLoop *loop) { + IROLinear *addvalue_mult; + IROLinear *addvalue; + IROLinear *mul; + IROLinear *sub; + IROLinear *add; + IROLinear *ass; + Type *type; + Object *tempobj; + ENode *expr; + + type = iterCount->rtype; + + addvalue_mult = IRO_NewLinear(IROLinearOperand); + addvalue_mult->index = ++IRO_NumLinear; + addvalue_mult->rtype = type; + expr = IRO_NewENode(EINTCONST); + expr->rtype = type; + CInt64_SetLong(&expr->data.intval, loop->induction->addConst * unrollFactor); + addvalue_mult->u.node = expr; + IRO_AddToList(addvalue_mult, list); + addvalue_mult->flags |= IROLF_Reffed; + + addvalue = IRO_NewLinear(IROLinearOperand); + addvalue->index = ++IRO_NumLinear; + addvalue->rtype = type; + expr = IRO_NewENode(EINTCONST); + expr->rtype = type; + CInt64_SetLong(&expr->data.intval, loop->induction->addConst); + addvalue->u.node = expr; + IRO_AddToList(addvalue, list); + addvalue->flags |= IROLF_Reffed; + + mul = IRO_NewLinear(IROLinearOp2Arg); + mul->index = ++IRO_NumLinear; + mul->nodetype = EMUL; + mul->u.diadic.left = IRO_DuplicateExpr(iterCount, list); + mul->u.diadic.right = addvalue; + mul->rtype = type; + IRO_AddToList(mul, list); + mul->flags |= IROLF_Reffed; + mul->u.diadic.left->flags &= ~IROLF_Assigned; + mul->u.diadic.left->u.diadic.left->flags &= ~IROLF_Assigned; + + sub = IRO_NewLinear(IROLinearOp2Arg); + sub->index = ++IRO_NumLinear; + sub->nodetype = ESUB; + sub->u.diadic.left = mul; + sub->u.diadic.right = addvalue_mult; + sub->rtype = type; + IRO_AddToList(sub, list); + sub->flags |= IROLF_Reffed; + + if (loop->induction->nd->type == IROLinearOp1Arg) + IRO_DuplicateExpr(loop->induction->nd->u.monadic, list); + else + IRO_DuplicateExpr(loop->induction->nd->u.diadic.left, list); + list->tail->flags &= ~IROLF_Assigned; + list->tail->u.diadic.left->flags &= ~IROLF_Assigned; + + add = IRO_NewLinear(IROLinearOp2Arg); + add->index = ++IRO_NumLinear; + add->nodetype = EADD; + add->u.diadic.left = sub; + add->u.diadic.right = list->tail; + add->rtype = type; + IRO_AddToList(add, list); + add->flags |= IROLF_Reffed; + + tempobj = create_temp_object(type); + IRO_FindVar(tempobj, 1, 1); + + ass = IRO_NewLinear(IROLinearOp2Arg); + ass->index = ++IRO_NumLinear; + ass->nodetype = EASS; + ass->u.diadic.left = IRO_TempReference(tempobj, list); + ass->u.diadic.left->flags |= IROLF_Assigned | IROLF_Ind; + ass->u.diadic.left->u.monadic->flags |= IROLF_Assigned | IROLF_Ind; + ass->u.diadic.right = add; + ass->u.diadic.right->flags |= IROLF_Reffed; + ass->rtype = type; + IRO_AddToList(ass, list); + + return ass->u.diadic.left; } -void BuildUnrolledBodyEntryTest() { +void BuildUnrolledBodyEntryTest(IROList *list, IROLinear *iterCount, UInt32 unrollFactor, CLabel *label) { + Type *type; + IROLinear *ifnot; + IROLinear *comp; + IROLinear *var; + IROLinear *value; + ENode *expr; + + type = iterCount->rtype; + + value = IRO_NewLinear(IROLinearOperand); + value->index = ++IRO_NumLinear; + value->rtype = type; + expr = IRO_NewENode(EINTCONST); + expr->rtype = type; + CInt64_SetLong(&expr->data.intval, unrollFactor); + value->u.node = expr; + IRO_AddToList(value, list); + + var = IRO_DuplicateExpr(iterCount, list); + + comp = IRO_NewLinear(IROLinearOp2Arg); + comp->index = ++IRO_NumLinear; + comp->nodetype = EGREATER; + comp->u.diadic.left = var; + comp->u.diadic.right = value; + comp->u.diadic.right->flags |= IROLF_Reffed; + comp->rtype = type; + IRO_AddToList(comp, list); + + ifnot = IRO_NewLinear(IROLinearOp1Arg); + ifnot->index = ++IRO_NumLinear; + ifnot->type = IROLinearIfNot; + ifnot->u.label.x4 = comp; + ifnot->u.label.x4->flags |= IROLF_Reffed; + ifnot->rtype = type; + ifnot->u.label.label = label; + IRO_AddToList(ifnot, list); } -void ChangeInductionReference() { +void ChangeInductionReference(IROLinear *first, IROLinear *last, CInt64 val, IROLoop *loop) { + IROLinear *nd; + IROLinear *value; + IROLinear *add; + UInt32 isUnsigned; + IROLinear *father; + Boolean flag; + IROLinear *father2; + IROLinear *father3; + Type *tmp; + UInt32 flag2; + Object *varobj; + IROLinear *next; + ENode *expr; + Type *type; + + CInt64 val2; + CInt64 val1; + IROList list; + + type = loop->induction->nd->rtype; + isUnsigned = IRO_IsUnsignedType(type); + + for (nd = first; nd; nd = next) { + next = nd->next; + + varobj = IRO_IsVariable(nd); + if (varobj && loop->induction->var->object == varobj) { + value = IRO_NewLinear(IROLinearOperand); + value->index = ++IRO_NumLinear; + value->rtype = type; + expr = IRO_NewENode(EINTCONST); + expr->rtype = type; + expr->data.intval = val; + value->u.node = expr; + + add = IRO_NewLinear(IROLinearOp2Arg); + add->index = ++IRO_NumLinear; + add->nodetype = EADD; + add->rtype = type; + + father = IRO_LocateFather(nd); + flag = 1; + if (father && IS_LINEAR_MONADIC(father, ETYPCON)) { + tmp = father->rtype; + father = IRO_LocateFather(father); + if (tmp->type != nd->rtype->type || tmp->size < nd->rtype->size) + flag = 0; + } + + flag2 = 0; + if ( + flag && + father && + IS_LINEAR_DIADIC_2(father, ESHL, EMUL) && + IRO_IsIntConstant(father->u.diadic.right) && + (father2 = IRO_LocateFather(father)) && + IS_LINEAR_DIADIC(father2, EADD) && + father2->u.diadic.right == father && + (father3 = IRO_LocateFather(father2)) + ) + { + IRO_InitList(&list); + val2 = father->u.diadic.right->u.node->data.intval; + if (father->nodetype == ESHL) + val2 = CInt64_Shl(cint64_one, val2); + + val1 = value->u.node->data.intval; + if (isUnsigned) + val1 = CInt64_MulU(val2, val1); + else + val1 = CInt64_Mul(val2, val1); + value->u.node->data.intval = val1; + + IRO_AddToList(value, &list); + IRO_AddToList(add, &list); + add->u.diadic.right = value; + IRO_Paste(list.head, list.tail, father3); + IRO_LocateFather_Cut_And_Paste_Without_Nopping(father2, add); + add->u.diadic.left = father2; + add->rtype = father2->rtype; + flag2 = 1; + } + + if (!flag2) { + add->u.diadic.right = value; + add->u.diadic.right->flags |= IROLF_Reffed; + value->next = add; + + add->u.diadic.left = nd; + IRO_LocateFather_Cut_And_Paste_Without_Nopping(nd, add); + add->flags |= IROLF_Reffed; + + nd->next = value; + add->next = next; + } + } + + if (nd == last) + break; + } } -void UpdateInductionIncrement() { +IROLinear *UpdateInductionIncrement(IROLoop *loop, SInt32 value, IROLinear *before) { + IROLinear *ind_nd; + IROLinear *addvalue; + IROLinear *ass; + Type *type; + ENode *expr; + IROList list; + + IRO_InitList(&list); + ind_nd = loop->induction->nd; + type = ind_nd->rtype; + + addvalue = IRO_NewLinear(IROLinearOperand); + addvalue->index = ++IRO_NumLinear; + addvalue->rtype = type; + expr = IRO_NewENode(EINTCONST); + expr->rtype = type; + CInt64_SetLong(&expr->data.intval, value * loop->induction->addConst); + addvalue->u.node = expr; + IRO_AddToList(addvalue, &list); + + if (IS_LINEAR_MONADIC_2(ind_nd, EPREINC, EPOSTINC)) { + ind_nd = IRO_DuplicateExpr(ind_nd->u.monadic, &list); + + ass = IRO_NewLinear(IROLinearOp2Arg); + ass->index = ++IRO_NumLinear; + ass->nodetype = EADDASS; + ass->u.diadic.left = ind_nd; + ass->u.diadic.right = addvalue; + ass->rtype = type; + IRO_AddToList(ass, &list); + } else if (IS_LINEAR_MONADIC_2(ind_nd, EPREDEC, EPOSTDEC)) { + ind_nd = IRO_DuplicateExpr(ind_nd->u.monadic, &list); + + ass = IRO_NewLinear(IROLinearOp2Arg); + ass->index = ++IRO_NumLinear; + ass->nodetype = ESUBASS; + ass->u.diadic.left = ind_nd; + ass->u.diadic.right = addvalue; + ass->rtype = type; + IRO_AddToList(ass, &list); + } else if (IS_LINEAR_DIADIC(ind_nd, EADDASS)) { + ind_nd = IRO_DuplicateExpr(ind_nd->u.monadic, &list); + + ass = IRO_NewLinear(IROLinearOp2Arg); + ass->index = ++IRO_NumLinear; + ass->nodetype = EADDASS; + ass->u.diadic.left = ind_nd; + ass->u.diadic.right = addvalue; + ass->rtype = type; + IRO_AddToList(ass, &list); + } + + IRO_Paste(list.head, list.tail, before); + return list.tail; } -void GenInitialAssignment() { +void GenInitialAssignment(IROLoop *loop, Object *var, IROList *list) { + Type *type; + IROLinear *nd; + + CError_ASSERT(3924, loop->nd14 && loop->nd14->type == IROLinearOp2Arg); + + type = loop->induction->nd->rtype; + + nd = IRO_NewLinear(IROLinearOp2Arg); + nd->index = ++IRO_NumLinear; + nd->nodetype = EASS; + nd->u.diadic.left = IRO_TempReference(var, list); + nd->u.diadic.right = IRO_DuplicateExpr(loop->nd14->u.diadic.right, list); + nd->rtype = type; + IRO_AddToList(nd, list); } -void GenNewInduction() { +void GenNewInduction(void) { + CError_FATAL(3941); } diff --git a/compiler_and_linker/unsorted/IroUtil.c b/compiler_and_linker/unsorted/IroUtil.c index 67edd4b..53e6733 100644 --- a/compiler_and_linker/unsorted/IroUtil.c +++ b/compiler_and_linker/unsorted/IroUtil.c @@ -956,10 +956,40 @@ void IRO_ReplaceReferenceWithNode(IROLinear *a, IROLinear *b) { } } -void IRO_GetTemp(IROExpr *expr) { +VarRecord *IRO_GetTemp(IROExpr *expr) { + expr->x8 = create_temp_object(expr->linear->rtype); + return IRO_FindVar(expr->x8, 1, 1); } IROLinear *IRO_AssignToTemp(IROExpr *expr) { + IROLinear *objref; + IROLinear *ind; + IROLinear *ass; + + objref = IRO_NewLinear(IROLinearOperand); + objref->u.node = create_objectrefnode(expr->x8); + objref->rtype = objref->u.node->data.objref->type; + objref->index = ++IRO_NumLinear; + objref->flags |= IROLF_Reffed | IROLF_Assigned | IROLF_Ind; + + ind = IRO_NewLinear(IROLinearOp1Arg); + ind->nodetype = EINDIRECT; + ind->rtype = expr->linear->rtype; + ind->u.monadic = objref; + ind->index = ++IRO_NumLinear; + ind->flags |= IROLF_Reffed | IROLF_Assigned; + + ass = IRO_NewLinear(IROLinearOp2Arg); + ass->nodetype = EASS; + ass->u.diadic.left = ind; + ass->u.diadic.right = expr->linear; + ass->rtype = expr->linear->rtype; + ass->index = ++IRO_NumLinear; + + objref->next = ind; + ind->next = ass; + IRO_PasteAfter(objref, ass, expr->linear); + return ass; } IROLinear *IRO_FindStart(IROLinear *linear) { @@ -993,7 +1023,7 @@ void IRO_RemoveCommaNodeFromIR(void) { if (!linear) break; if (linear->nodetype == ECOMMA) { - linear->u.diadic.left->flags &= ~IROLF_Reffed; + linear->u.diadic.left->flags = linear->u.diadic.left->flags & ~IROLF_Reffed; IRO_LocateFather_Cut_And_Paste_Without_Nopping(linear, linear->u.diadic.right); linear->type = IROLinearNop; } @@ -1200,7 +1230,7 @@ IROLinear *IRO_NewIntConst(CInt64 val, Type *type) { return linear; } -IROLinear *IRO_NewFloatConst(Float val, Type *type) { +IROLinear *IRO_NewFloatConst(const Float val, Type *type) { ENode *node; IROLinear *linear; @@ -1230,4 +1260,3 @@ void IRO_CheckForUserBreak(void) { IRO_LastUserBreakTick = COS_GetTicks(); } } - diff --git a/compiler_and_linker/unsorted/IroVars.c b/compiler_and_linker/unsorted/IroVars.c index a40656a..15e7e65 100644 --- a/compiler_and_linker/unsorted/IroVars.c +++ b/compiler_and_linker/unsorted/IroVars.c @@ -1113,7 +1113,7 @@ void IRO_ScalarizeClassDataMembers(void) { } if (nd->type == IROLinearAsm) { IAEffects effects; - int i; + SInt32 i; CodeGen_GetAsmEffects(nd->u.asm_stmt, &effects); for (i = 0; i < effects.numoperands; i++) { if ((var = IRO_FindVar(effects.operands[i].object, 0, 1))) diff --git a/compiler_and_linker/unsorted/LoopOptimization.c b/compiler_and_linker/unsorted/LoopOptimization.c index 1c0b905..c2a360f 100644 --- a/compiler_and_linker/unsorted/LoopOptimization.c +++ b/compiler_and_linker/unsorted/LoopOptimization.c @@ -843,19 +843,19 @@ static void rewriteunknownloopwithBDNZ(Loop *loop) { if (loop->unknownCondition == ELESS) { branchOpcode = PC_BF; if (loop->lowerType == LOOP_BOUND_CONSTANT) { - branchCondition = 1; + branchCondition = 1; // GT value1 = loop->lower; reg1 = addiInstr->args[2].data.reg.reg; value2 = absStep - 1 - loop->lower; mode = 0; } else if (loop->upperType == LOOP_BOUND_CONSTANT) { - branchCondition = 0; + branchCondition = 0; // LT value1 = loop->upper; reg1 = addiInstr->args[1].data.reg.reg; value2 = absStep - 1 + loop->upper; mode = 1; } else { - branchCondition = 0; + branchCondition = 0; // LT reg1 = addiInstr->args[1].data.reg.reg; reg2 = addiInstr->args[2].data.reg.reg; value2 = absStep - 1; @@ -864,19 +864,19 @@ static void rewriteunknownloopwithBDNZ(Loop *loop) { } else if (loop->unknownCondition == ELESSEQU) { branchOpcode = PC_BT; if (loop->lowerType == LOOP_BOUND_CONSTANT) { - branchCondition = 0; + branchCondition = 0; // LT value1 = loop->lower; reg1 = addiInstr->args[2].data.reg.reg; value2 = absStep - loop->lower; mode = 0; } else if (loop->upperType == LOOP_BOUND_CONSTANT) { - branchCondition = 1; + branchCondition = 1; // GT value1 = loop->upper; reg1 = addiInstr->args[1].data.reg.reg; value2 = absStep + loop->upper; mode = 1; } else { - branchCondition = 1; + branchCondition = 1; // GT value1 = 0; reg1 = addiInstr->args[1].data.reg.reg; reg2 = addiInstr->args[2].data.reg.reg; @@ -886,19 +886,19 @@ static void rewriteunknownloopwithBDNZ(Loop *loop) { } else if (loop->unknownCondition == EGREATER) { branchOpcode = PC_BF; if (loop->lowerType == LOOP_BOUND_CONSTANT) { - branchCondition = 0; + branchCondition = 0; // LT value1 = loop->lower; reg1 = addiInstr->args[2].data.reg.reg; value2 = absStep - 1 + loop->lower; mode = 1; } else if (loop->upperType == LOOP_BOUND_CONSTANT) { - branchCondition = 1; + branchCondition = 1; // GT value1 = loop->upper; reg1 = addiInstr->args[1].data.reg.reg; value2 = absStep - 1 - loop->upper; mode = 0; } else { - branchCondition = 1; + branchCondition = 1; // GT value1 = 0; reg1 = addiInstr->args[1].data.reg.reg; reg2 = addiInstr->args[2].data.reg.reg; @@ -908,19 +908,19 @@ static void rewriteunknownloopwithBDNZ(Loop *loop) { } else if (loop->unknownCondition == EGREATEREQU) { branchOpcode = PC_BT; if (loop->lowerType == LOOP_BOUND_CONSTANT) { - branchCondition = 1; + branchCondition = 1; // GT value1 = loop->lower; reg1 = addiInstr->args[2].data.reg.reg; value2 = absStep + loop->lower; mode = 1; } else if (loop->upperType == LOOP_BOUND_CONSTANT) { - branchCondition = 0; + branchCondition = 0; // LT value1 = loop->upper; reg1 = addiInstr->args[1].data.reg.reg; value2 = absStep - loop->upper; mode = 0; } else { - branchCondition = 0; + branchCondition = 0; // LT reg1 = addiInstr->args[1].data.reg.reg; reg2 = addiInstr->args[2].data.reg.reg; value2 = absStep; @@ -928,7 +928,7 @@ static void rewriteunknownloopwithBDNZ(Loop *loop) { } } else if (loop->unknownCondition == ENOTEQU) { branchOpcode = PC_BT; - branchCondition = 2; + branchCondition = 2; // EQ if (loop->step > 0) { if (loop->lowerType == LOOP_BOUND_CONSTANT) { value1 = loop->lower; diff --git a/compiler_and_linker/unsorted/RegisterInfo.c b/compiler_and_linker/unsorted/RegisterInfo.c index a5e9966..91d775f 100644 --- a/compiler_and_linker/unsorted/RegisterInfo.c +++ b/compiler_and_linker/unsorted/RegisterInfo.c @@ -75,7 +75,7 @@ void retain_GPR_pair(Object *obj, short reg, short regHi) { } int is_register_object(Object *obj) { - return obj->sclass == OBJECT_SCLASS_101; + return obj->sclass == TK_REGISTER; } int GetABIFirstNonVolatile(RegClass rclass) { @@ -118,10 +118,9 @@ void setup_diagnostic_reg_strings(void) { } void init_target_registers(void) { - RegClass rclass; int reg; int end; - int tmp; + RegClass rclass; static int last_nonvolatile_reg[] = {3, 5, 31, 31, 31}; static int nonvol_reserve[] = {0, 0, 0, 4, 3}; @@ -153,8 +152,7 @@ void init_target_registers(void) { end = first_nonvolatile_reg(rclass); for (reg = last_nonvolatile_reg[rclass]; reg >= end; reg--) { if (reg_state[rclass][reg] == RegState0) { - tmp = n_nonvolatile_registers[rclass]++; - nonvolatile_registers[rclass][tmp] = reg; + nonvolatile_registers[rclass][n_nonvolatile_registers[rclass]++] = reg; } } } @@ -167,8 +165,7 @@ void init_target_registers(void) { for (reg = 0; reg < n_real_registers[rclass]; reg++) { if (reg < GetABIFirstNonVolatile(rclass) || reg > last_nonvolatile_reg[rclass]) { if (reg_state[rclass][reg] == RegState0) { - tmp = n_scratch_registers[rclass]++; - scratch_registers[rclass][tmp] = reg; + scratch_registers[rclass][n_scratch_registers[rclass]++] = reg; } } } @@ -250,9 +247,6 @@ void open_fe_temp_registers(void) { first_fe_temporary_register[RegClass_FPR] = last_temporary_register[RegClass_FPR] = r; r = used_virtual_registers[RegClass_VR]; first_fe_temporary_register[RegClass_VR] = last_temporary_register[RegClass_VR] = r; - //first_fe_temporary_register[RegClass_GPR] = last_temporary_register[RegClass_GPR] = used_virtual_registers[RegClass_GPR]; - //first_fe_temporary_register[RegClass_FPR] = last_temporary_register[RegClass_FPR] = used_virtual_registers[RegClass_FPR]; - //first_fe_temporary_register[RegClass_VR] = last_temporary_register[RegClass_VR] = used_virtual_registers[RegClass_VR]; } void set_last_exception_registers(void) { @@ -371,14 +365,17 @@ void init_endian(void) { void update_asm_nonvolatile_registers(void) { RegClass rclass; - int r31; + int i; + int reg; for (rclass = 0; rclass < RegClassMax; rclass++) { - for (r31 = n_nonvolatile_registers[rclass] - 1; r31 >= 0; r31--) { - if (reg_state[rclass][nonvolatile_registers[rclass][r31]] == RegState1) + reg = n_nonvolatile_registers[rclass]; + for (i = n_nonvolatile_registers[rclass] - 1; i >= 0; i--) { + if (reg_state[rclass][nonvolatile_registers[rclass][i]] == RegState1) break; + reg--; } - if (r31 > used_nonvolatile_registers[rclass]) - used_nonvolatile_registers[rclass] = r31; + if (reg > used_nonvolatile_registers[rclass]) + used_nonvolatile_registers[rclass] = reg; } } diff --git a/compiler_and_linker/unsorted/StackFrame.c b/compiler_and_linker/unsorted/StackFrame.c index a78552d..91b15da 100644 --- a/compiler_and_linker/unsorted/StackFrame.c +++ b/compiler_and_linker/unsorted/StackFrame.c @@ -71,8 +71,8 @@ static void restore_nonvolatile_GPRs(int reg, SInt32 offset); static void do_allocate_dynamic_stack_space(Boolean isConstantSize, int reg1, int reg2, SInt32 size); void init_stack_globals(Object *funcobj) { - char rclass; - UInt8 oclass; + RegClass rclass; + ObjClass oclass; requires_frame = 0; makes_call = 0; @@ -109,7 +109,7 @@ void init_stack_globals(Object *funcobj) { LR_save_offset = -1; for (rclass = 0; rclass < RegClassMax; rclass++) - non_volatile_save_offset[(char) rclass] = -1; + non_volatile_save_offset[rclass] = -1; dummyprofiler = NULL; dummyvaparam = NULL; diff --git a/compiler_and_linker/unsorted/TOC.c b/compiler_and_linker/unsorted/TOC.c index 49ae3e1..3fde61b 100644 --- a/compiler_and_linker/unsorted/TOC.c +++ b/compiler_and_linker/unsorted/TOC.c @@ -10,8 +10,12 @@ #include "compiler/CMangler.h" #include "compiler/CParser.h" #include "compiler/CodeGen.h" +#include "compiler/CompilerTools.h" #include "compiler/Exceptions.h" +#include "compiler/InlineAsm.h" +#include "compiler/InlineAsmPPC.h" #include "compiler/InstrSelection.h" +#include "compiler/Intrinsics.h" #include "compiler/ObjGenMachO.h" #include "compiler/Operands.h" #include "compiler/PCode.h" @@ -19,7 +23,6 @@ #include "compiler/PPCError.h" #include "compiler/RegisterInfo.h" #include "compiler/StackFrame.h" -#include "compiler/CompilerTools.h" #include "compiler/enode.h" #include "compiler/objects.h" #include "compiler/types.h" @@ -27,10 +30,10 @@ ObjectList *toclist; ObjectList *exceptionlist; void *descriptorlist; -void *floatconstpool; -void *doubleconstpool; +PoolEntry *floatconstpool; +PoolEntry *doubleconstpool; ObjectList *floatconstlist; -void *vectorconstpool; +PoolEntry *vectorconstpool; ObjectList *vectorconstlist; Object toc0; Boolean no_descriptors; @@ -126,7 +129,7 @@ void createNonLazyPointer(Object *obj) { toc->toc = NULL; toc->section = SECT_NONLAZY_PTRS; toc->u.toc.info = CodeGen_GetNewVarInfo(); - toc->sclass = OBJECT_SCLASS_102; + toc->sclass = TK_STATIC; toc->qual = Q_CONST; toc->datatype = DNONLAZYPTR; toc->flags |= OBJECT_FLAGS_2; @@ -193,7 +196,7 @@ Object *createfloatconstant(Type *type, Float *data) { obj->toc = NULL; obj->u.data.info = NULL; obj->u.data.linkname = obj->name; - obj->sclass = OBJECT_SCLASS_102; + obj->sclass = TK_STATIC; obj->qual = Q_CONST | Q_10000; obj->datatype = DDATA; if (type->size == 8) @@ -238,7 +241,7 @@ Object *createvectorconstant(Type *type, MWVector128 *data) { obj->toc = NULL; obj->u.data.info = NULL; obj->u.data.linkname = obj->name; - obj->sclass = OBJECT_SCLASS_102; + obj->sclass = TK_STATIC; obj->qual = Q_CONST | Q_10000; obj->datatype = DDATA; if (type->size == 16) @@ -261,16 +264,153 @@ Object *createvectorconstant(Type *type, MWVector128 *data) { return obj; } -void DeclarePooledConstants() { - // TODO CInit +void DeclarePooledConstants(void) { + PoolEntry *entry; + char *buffer; + SInt32 fsize; + SInt32 dsize; + SInt32 vsize; + + fsize = 0; + for (entry = floatconstpool; entry; entry = entry->next) + fsize += 4; + + if (fsize) { + floatconstpool->object->type = CDecl_NewArrayType(TYPE(&stfloat), fsize); + buffer = galloc(fsize); + for (entry = floatconstpool; entry; entry = entry->next) + memcpy(buffer + entry->offset, entry->buffer, 4); + CInit_DeclareReadOnlyData(floatconstpool->object, buffer, NULL, fsize); + } + + dsize = 0; + for (entry = doubleconstpool; entry; entry = entry->next) + dsize += 8; + + if (dsize) { + doubleconstpool->object->type = CDecl_NewArrayType(TYPE(&stdouble), dsize); + buffer = galloc(dsize); + for (entry = doubleconstpool; entry; entry = entry->next) + memcpy(buffer + entry->offset, entry->buffer, 8); + CInit_DeclareReadOnlyData(doubleconstpool->object, buffer, NULL, dsize); + } + + vsize = 0; + for (entry = vectorconstpool; entry; entry = entry->next) + vsize += 16; + + if (vsize) { + vectorconstpool->object->type = CDecl_NewArrayType(TYPE(&stvectorsignedlong), vsize); + buffer = galloc(vsize); + for (entry = vectorconstpool; entry; entry = entry->next) + memcpy(buffer + entry->offset, entry->buffer, 16); + CInit_DeclareReadOnlyData(vectorconstpool->object, buffer, NULL, vsize); + } } -static Object *CreatePooledFloatConst(Type *type, Float *data, SInt32 *unkptr) { - // TODO CDecl +static Object *CreatePooledFloatConst(Type *type, Float *data, SInt32 *pOffset) { + if (type->size == 8u) { + PoolEntry *entry; + void *buffer; + Object *object; + SInt32 offset; + + buffer = galloc(8u); + CMach_InitFloatMem(type, *data, buffer); + if (cparamblkptr->isPrecompiling == 1) + CError_Error(CErrorStr180); + + for (entry = doubleconstpool; entry; entry = entry->next) { + if (!memcmp(entry->buffer, buffer, 8u)) + break; + } + + if (!entry) { + if (doubleconstpool) { + object = doubleconstpool->object; + offset = doubleconstpool->offset + 8u; + doubleconstpool->object->type->size += 8u; + } else { + DeclInfo di; + memclrw(&di, sizeof(di)); + di.thetype = CDecl_NewArrayType(TYPE(&stdouble), 8u); + di.name = GetHashNameNodeExport("@doubleBase0"); + di.qual = Q_CONST; + di.storageclass = TK_STATIC; + di.x4E = 1; + di.section = SECT_CONST; + object = CParser_NewGlobalDataObject(&di); + object->nspace = cscope_root; + offset = 0; + } + + entry = galloc(sizeof(PoolEntry)); + entry->next = doubleconstpool; + doubleconstpool = entry; + entry->object = object; + entry->offset = offset; + entry->buffer = galloc(8u); + memcpy(entry->buffer, buffer, 8u); + } + + *pOffset = entry->offset; + return entry->object; + } + + if (type->size == 4u) { + PoolEntry *entry; + void *buffer; + Object *object; + SInt32 offset; + + buffer = galloc(4u); + CMach_InitFloatMem(type, *data, buffer); + if (cparamblkptr->isPrecompiling == 1) + CError_Error(CErrorStr180); + + for (entry = floatconstpool; entry; entry = entry->next) { + if (!memcmp(entry->buffer, buffer, 4u)) + break; + } + + if (!entry) { + if (floatconstpool) { + object = floatconstpool->object; + offset = floatconstpool->offset + 4u; + object->type->size += 4u; + } else { + DeclInfo di; + memclrw(&di, sizeof(di)); + di.thetype = CDecl_NewArrayType(TYPE(&stfloat), 4u); + di.name = GetHashNameNodeExport("@floatBase0"); + di.qual = Q_CONST; + di.storageclass = TK_STATIC; + di.x4E = 1; + di.section = SECT_CONST; + object = CParser_NewGlobalDataObject(&di); + object->nspace = cscope_root; + offset = 0; + } + + entry = galloc(sizeof(PoolEntry)); + entry->next = floatconstpool; + floatconstpool = entry; + entry->object = object; + entry->offset = offset; + entry->buffer = galloc(4u); + memcpy(entry->buffer, buffer, 4u); + } + + *pOffset = entry->offset; + return entry->object; + } + + CError_FATAL(1183); + return NULL; } -Object *CreateFloatConst(Type *type, Float *data, SInt32 *unkptr) { - *unkptr = 0; +Object *CreateFloatConst(Type *type, Float *data, SInt32 *pOffset) { + *pOffset = 0; return createfloatconstant(type, data); } @@ -281,7 +421,7 @@ static void RewriteFloatConst(ENode *expr) { obj = CreateFloatConst(expr->rtype, &expr->data.floatval, &n); if (n) { - subexpr = makediadicnode(create_objectrefnode(obj), intconstnode(&stunsignedlong, n), EADD); + subexpr = makediadicnode(create_objectrefnode(obj), intconstnode(TYPE(&stunsignedlong), n), EADD); } else { subexpr = create_objectrefnode(obj); } @@ -293,8 +433,63 @@ static void RewriteFloatConst(ENode *expr) { } static void RewriteVectorConst(ENode *expr) { + PoolEntry *entry; + Object *object; + SInt32 offset; + ENode *inner; UInt8 data[16]; - // TODO + + CMach_InitVectorMem(expr->rtype, expr->data.vector128val, data, 1); + + if (cparamblkptr->isPrecompiling == 1) + CError_Error(CErrorStr180); + + for (entry = vectorconstpool; entry; entry = entry->next) { + if (!memcmp(entry->buffer, data, 16)) + break; + } + + if (!entry) { + if (vectorconstpool) { + object = vectorconstpool->object; + offset = vectorconstpool->offset + 16; + vectorconstpool->object->type->size += 16; + } else { + DeclInfo di; + memclrw(&di, sizeof(di)); + di.thetype = CDecl_NewArrayType(TYPE(&stvectorsignedlong), 16); + di.name = GetHashNameNodeExport("@vectorBase0"); + di.qual = Q_CONST; + di.storageclass = TK_STATIC; + di.x4E = 1; + di.section = SECT_CONST; + object = CParser_NewGlobalDataObject(&di); + object->nspace = cscope_root; + offset = 0; + } + + entry = galloc(sizeof(PoolEntry)); + entry->next = vectorconstpool; + vectorconstpool = entry; + entry->object = object; + entry->offset = offset; + entry->buffer = galloc(16); + memcpy(entry->buffer, data, 16); + } + + if (entry->offset) { + inner = makediadicnode( + create_objectrefnode(entry->object), + intconstnode(TYPE(&stunsignedlong), entry->offset), + EADD); + } else { + inner = create_objectrefnode(entry->object); + } + + expr->type = EINDIRECT; + expr->cost = 1; + expr->flags |= ENODE_FLAG_CONST; + expr->data.monadic = inner; } static Object *createcodelabel(CLabel *label) { @@ -313,7 +508,7 @@ static Object *createcodelabel(CLabel *label) { obj->name = label->uniquename; obj->toc = NULL; obj->u.data.info = NULL; // not sure if this is the right union! - obj->sclass = OBJECT_SCLASS_102; + obj->sclass = TK_STATIC; obj->qual = Q_CONST; obj->datatype = DDATA; obj->flags |= OBJECT_FLAGS_2 | OBJECT_FLAGS_4; @@ -748,9 +943,13 @@ Boolean canoptimizevectorconst(MWVector128 *vecp, Type *type, COVCResult *result first8 = vec.sc[0]; flag = 1; - for (i = 0; flag && i < 16; i++) { + i = 1; + while (flag && i < 16) + flag = first8 == vec.sc[i++]; + /*flag = 1; + for (i = 1; flag && i < 16; i++) { flag = first8 == vec.sc[i]; - } + }*/ if (flag && first8 < 16 && first8 > -17) { if (result) { @@ -954,6 +1153,12 @@ static Boolean DetectCondSideAffect(ENode *expr) { case EXOR: case EOR: case ECOMMA: + case EPMODULO: + case EROTL: + case EROTR: + case EBCLR: + case EBTST: + case EBSET: if (DetectCondSideAffect(expr->data.diadic.left)) return 1; return DetectCondSideAffect(expr->data.diadic.right); @@ -961,7 +1166,7 @@ static Boolean DetectCondSideAffect(ENode *expr) { if (expr->data.monadic->type == EINDIRECT) return 1; if (expr->data.monadic->type == EOBJREF) { - if (expr->data.monadic->data.objref->datatype != DDATA && expr->data.monadic->data.objref->datatype != DLOCAL) + if (expr->data.monadic->data.objref->datatype != DLOCAL && expr->data.monadic->data.objref->datatype != DDATA) return 1; if (IS_TYPE_POINTER(expr->data.monadic->data.objref->type)) return 1; @@ -1509,12 +1714,12 @@ static void expandTOCexpression(ENode *expr, Type *type, int ignored) { case EFUNCCALLP: if (is_intrinsic_function_call(expr)) { expr->hascall = 0; - if ((expr->data.funccall.funcref->data.objref->u.func.u.intrinsicid & 0xFFFFu) == INTRINSIC_8) { + if ((expr->data.funccall.funcref->data.objref->u.func.u.intrinsicid & 0xFFFFu) == Intrinsic_008) { if (copts.altivec_model) update_frame_align(16); dynamic_stack = 1; requires_frame = 1; - } else if ((expr->data.funccall.funcref->data.objref->u.func.u.intrinsicid & 0xFFFFu) == INTRINSIC_35) { + } else if ((expr->data.funccall.funcref->data.objref->u.func.u.intrinsicid & 0xFFFFu) == Intrinsic_035) { if (expr->data.funccall.args->next->node->type == ESTRINGCONST) { rewritestrcpy(expr); } else { @@ -1522,7 +1727,7 @@ static void expandTOCexpression(ENode *expr, Type *type, int ignored) { makes_call = 1; expr->hascall = 1; } - } else if ((expr->data.funccall.funcref->data.objref->u.func.u.intrinsicid & 0xFFFFu) == INTRINSIC_36) { + } else if ((expr->data.funccall.funcref->data.objref->u.func.u.intrinsicid & 0xFFFFu) == Intrinsic_036) { if (expr->data.funccall.args->next->next->node->type != EINTCONST) { requires_frame = 1; makes_call = 1; @@ -1929,6 +2134,10 @@ static void checkexceptionreferences(ExceptionAction *action) { void expandTOCreferences(Statement **stmts) { Statement *stmt; + IAOperand *op; + int i; + InlineAsm *ia; + VarInfo *vi; codelabellist = NULL; exceptionlist = NULL; @@ -1952,7 +2161,7 @@ void expandTOCreferences(Statement **stmts) { break; case ST_IFGOTO: case ST_IFNGOTO: - if (stmt->expr->type >= ELESS && stmt->expr->type <= ENOTEQU) + if (stmt->expr->type < ELESS || stmt->expr->type > ENOTEQU) stmt->expr = comparewithzero(stmt->expr); expandTOCexpression(stmt->expr, NULL, 0); break; @@ -1973,8 +2182,29 @@ void expandTOCreferences(Statement **stmts) { makes_call = 1; break; case ST_ASM: - if (stmt->expr) { - // TODO - ASM weirdness here + if ((ia = (InlineAsm *) stmt->expr)) { + if (ia->flags & IAFlag1) { + if (ia->opcode == IADirective_FrFree) + requires_frame = 1; + } else { + for (i = 0, op = ia->args; i < ia->argcount; i++, op++) { + if (op->type == IAOpnd_Reg) { + if (!op->u.reg.object) { + if (op->u.reg.num == INVALID_PIC_REG) + uses_globals = 1; + else if (op->u.reg.effect & EffectWrite) + asm_used_register(op->u.reg.rclass, op->u.reg.num); + } else if ((vi = Registers_GetVarInfo(op->u.reg.object))) { + vi->flags |= VarInfoFlag40; + } + } else if (op->type == IAOpnd_3) { + uses_globals = 1; + } + } + + if (ia->flags & IAFlag2) + makes_call = 1; + } } break; } @@ -2021,7 +2251,7 @@ Object *createstaticinitobject(void) { obj->otype = OT_OBJECT; obj->type = (Type *) tfunc; obj->name = GetHashNameNodeExport(buf); - obj->sclass = OBJECT_SCLASS_102; + obj->sclass = TK_STATIC; obj->datatype = DFUNC; return obj; diff --git a/includes/compiler.h b/includes/compiler.h index cea535f..c811e6a 100644 --- a/includes/compiler.h +++ b/includes/compiler.h @@ -12,23 +12,7 @@ -struct DefArgCtorInfo { - Object *default_func; - ENode *default_arg; -}; - -typedef struct XRefOffset { - UInt32 xrefoffset; - SInt32 offset; -} XRefOffset; -struct InlineXRef { - InlineXRef *next; - Object *object; - UInt16 xrefmode; - UInt16 numxrefs; - XRefOffset xref[1]; -}; diff --git a/includes/compiler/CABI.h b/includes/compiler/CABI.h index 735eeea..6e190d5 100644 --- a/includes/compiler/CABI.h +++ b/includes/compiler/CABI.h @@ -8,6 +8,13 @@ #pragma options align=mac68k #endif +typedef enum CABIDestroyMode { + CABIDestroy0 = 0, + CABIDestroy1 = 1, + CABIDestroy2 = 2, + CABIDestroy3 = 3 +} CABIDestroyMode; + extern short CABI_GetStructResultArgumentIndex(TypeFunc *tfunc); extern Type *CABI_GetSizeTType(void); extern Type *CABI_GetPtrDiffTType(void); @@ -16,21 +23,21 @@ extern void CABI_ReverseBitField(TypeBitfield *tbitfield); extern void CABI_AddVTable(TypeClass *tclass); extern SInt32 CABI_GetVTableOffset(TypeClass *tclass); extern void CABI_LayoutClass(DeclE *decle, TypeClass *tclass); -extern void CABI_MakeDefaultArgConstructor(TypeClass *tclass, Object *obj); +extern void CABI_MakeDefaultArgConstructor(TypeClass *tclass, Object *func); extern ENode *CABI_MakeThisExpr(TypeClass *tclass, SInt32 offset); extern SInt32 CABI_GetCtorOffsetOffset(TypeClass *tclass, TypeClass *base); extern Object *CABI_ConstructorCallsNew(TypeClass *tclass); typedef Statement *(*TransConstructorCallback)(Statement *stmt, TypeClass *tclass, TypeClass *base, SInt32 offset, Boolean flag); -extern void CABI_TransConstructor(Object *obj, Statement *stmt, TypeClass *tclass, TransConstructorCallback callback, Boolean flag); -extern void CABI_MakeDefaultConstructor(TypeClass *tclass, Object *obj); -extern void CABI_MakeDefaultCopyConstructor(TypeClass *tclass, Object *obj); -extern void CABI_MakeDefaultAssignmentOperator(TypeClass *tclass, Object *obj); -extern void CABI_TransDestructor(Object *obj1, Object *obj2, Statement *stmt, TypeClass *tclass); -extern void CABI_MakeDefaultDestructor(TypeClass *tclass, Object *obj); -extern void CABI_MakeLayeredDestructor(TypeClass *tclass, Object *obj); -extern Object *CABI_GetDestructorObject(Object *obj, int what); +extern void CABI_TransConstructor(Object *obj, Statement *stmt, TypeClass *tclass, TransConstructorCallback callback, Boolean has_try); +extern void CABI_MakeDefaultConstructor(TypeClass *tclass, Object *func); +extern void CABI_MakeDefaultCopyConstructor(TypeClass *tclass, Object *func); +extern void CABI_MakeDefaultAssignmentOperator(TypeClass *tclass, Object *func); +extern void CABI_TransDestructor(Object *obj1, Object *obj2, Statement *stmt, TypeClass *tclass, CABIDestroyMode mode); +extern void CABI_MakeDefaultDestructor(TypeClass *tclass, Object *func); +extern void CABI_MakeLayeredDestructor(TypeClass *tclass, Object *func); +extern Object *CABI_GetDestructorObject(Object *obj, CABIDestroyMode mode); extern void CABI_AddLayeredDestructors(TypeClass *tclass); -extern ENode *CABI_DestroyObject(Object *dtor, ENode *objexpr, UInt8 mode, Boolean flag1, Boolean flag2); +extern ENode *CABI_DestroyObject(Object *dtor, ENode *objexpr, CABIDestroyMode mode, Boolean flag1, Boolean flag2); #ifdef __MWERKS__ #pragma options align=reset diff --git a/includes/compiler/CClass.h b/includes/compiler/CClass.h index 083588c..bb952de 100644 --- a/includes/compiler/CClass.h +++ b/includes/compiler/CClass.h @@ -7,21 +7,21 @@ #pragma options align=mac68k #endif -typedef struct VTableObjectLink { +/*typedef struct VTableObjectLink { struct VTableObjectLink *next; Object *methodobj; SInt32 offset; SInt32 xC; -} VTableObjectLink; +} VTableObjectLink;*/ extern void CClass_Init(void); extern void CClass_GenThunks(void); extern UInt8 CClass_GetOverrideKind(TypeFunc *a, TypeFunc *b, Boolean errorflag); extern Boolean CClass_IsEmpty(TypeClass *tclass); -extern Boolean CClass_IsNonStaticMemberFunc(TypeMethod *tmethod); +extern Boolean CClass_IsNonStaticMemberFunc(TypeFunc *tfunc); extern Object *CClass_DefaultConstructor(TypeClass *tclass); extern Object *CClass_DummyDefaultConstructor(TypeClass *tclass); -extern ENode *CClass_DefaultConstructorCall(TypeClass *a, TypeClass *b, ENode *expr, SInt32 unkshortparam, Boolean flag1, Boolean flag2, Boolean *errorflag); +extern ENode *CClass_DefaultConstructorCall(TypeClass *tclass, TypeClass *b, ENode *objexpr, SInt32 varg, Boolean flag1, Boolean flag2, Boolean *errorflag); extern Object *CClass_AssignmentOperator(TypeClass *tclass); extern Object *CClass_CopyConstructor(TypeClass *tclass); extern NameSpaceObjectList *CClass_MemberObject(TypeClass *tclass, HashNameNode *name); @@ -34,19 +34,19 @@ extern Boolean CClass_IsTrivialCopyClass(TypeClass *tclass); extern Boolean CClass_IsTrivialCopyAssignClass(TypeClass *tclass); extern Boolean CClass_ReferenceArgument(TypeClass *tclass); extern BClassList *CClass_GetPathCopy(BClassList *path, Boolean is_global); -extern BClassList *CClass_AppendPath(BClassList *a, BClassList *b); +extern BClassList *CClass_AppendPath(BClassList *dest, BClassList *src); extern Boolean CClass_IsMoreAccessiblePath(BClassList *path1, BClassList *path2); extern BClassList *CClass_GetBasePath(TypeClass *a, TypeClass *b, short *founddepth, Boolean *isambigbase); extern Boolean CClass_IsBaseClass(TypeClass *a, TypeClass *b, short *founddepth, Boolean pathcheckflag, Boolean ambigerrorflag); extern TypeClass *CClass_GetQualifiedClass(void); -extern ENode *CClass_AccessPathCast(BClassList *path, ENode *expr, Boolean flag); +extern ENode *CClass_AccessPathCast(BClassList *path, ENode *expr, Boolean reverse); extern ENode *CClass_ClassPointerCast(ENode *expr, TypeClass *a, TypeClass *b, Boolean typconflag, Boolean ambigerrorflag, Boolean pathcheckflag); extern ENode *CClass_DirectBasePointerCast(ENode *expr, TypeClass *a, TypeClass *b); extern SInt32 CClass_GetPathOffset(BClassList *path); -extern Boolean CClass_ClassDominates(TypeClass *a, TypeClass *b); -extern SInt32 CClass_VirtualBaseOffset(TypeClass *a, TypeClass *b); -extern SInt32 CClass_VirtualBaseVTableOffset(TypeClass *a, TypeClass *b); -extern SInt32 CClass_GetMemberOffset(TypeClass *tclass, HashNameNode *name, ObjMemberVar **obj); +extern Boolean CClass_ClassDominates(TypeClass *tclass, TypeClass *baseclass); +extern SInt32 CClass_VirtualBaseOffset(TypeClass *tclass, TypeClass *baseclass); +extern SInt32 CClass_VirtualBaseVTableOffset(TypeClass *tclass, TypeClass *baseclass); +extern SInt32 CClass_GetMemberOffset(TypeClass *tclass, HashNameNode *name, ObjMemberVar **resultIvar); extern Boolean CClass_OverridesBaseMember(TypeClass *tclass, HashNameNode *name, Object *obj); extern void CClass_DefineCovariantFuncs(Object *method, CI_FuncData *ifuncdata); extern void CClass_CheckOverrides(TypeClass *tclass); diff --git a/includes/compiler/CDecl.h b/includes/compiler/CDecl.h index a4c28e2..331a53b 100644 --- a/includes/compiler/CDecl.h +++ b/includes/compiler/CDecl.h @@ -12,7 +12,7 @@ // named because it's 0xE bytes big (hurr) struct DeclE { ObjBase **objlist; - void *x4; + ObjMemberVar *vtable_ivar; unsigned short x8; // lex_order_count? unsigned short xA; Boolean xC; @@ -31,8 +31,8 @@ struct DeclInfo { HashNameNode *name; Object *x10; NameSpaceObjectList *x14; - void *x18; - void *x1C; + FuncArg *x18; + NameSpace *x1C; Type *x20; ENode *x24; TemplClass *x28; @@ -46,8 +46,8 @@ struct DeclInfo { short storageclass; UInt8 section; UInt8 exportflags; - Boolean x44; - Boolean x45; + Boolean x44; // has args in identifier list + Boolean x45; // has oldstyle args Boolean x46; Boolean x47; Boolean x48; @@ -56,7 +56,7 @@ struct DeclInfo { Boolean x4B; Boolean x4C; Boolean x4D; - Boolean x4E; + Boolean x4E; // is_extern_c? Boolean x4F; Boolean x50; Boolean x51; @@ -70,7 +70,7 @@ struct DeclInfo { CPrepFileInfo *file; CPrepFileInfo *file2; SInt32 x60; // file offset? - short x64; + Boolean x64; }; typedef struct BigDeclInfo { diff --git a/includes/compiler/CException.h b/includes/compiler/CException.h index 0e19380..361cddd 100644 --- a/includes/compiler/CException.h +++ b/includes/compiler/CException.h @@ -3,6 +3,13 @@ #include "compiler/common.h" +typedef struct DtorTemp { + struct DtorTemp *next; + Object *object; + Object *dtor; + Object *temp; +} DtorTemp; + extern ExceptionAction *cexcept_dobjstack; extern Boolean cexcept_hasdobjects; extern Boolean cexcept_magic; diff --git a/includes/compiler/CExpr.h b/includes/compiler/CExpr.h index 24f0646..bdc0789 100644 --- a/includes/compiler/CExpr.h +++ b/includes/compiler/CExpr.h @@ -64,7 +64,9 @@ typedef struct Conversion { } Conversion; // CExpr.c -extern Boolean (*name_obj_check)(HashNameNode *, Object *); +typedef Boolean (*NameObjCheckCB)(HashNameNode *, Object *); + +extern NameObjCheckCB name_obj_check; extern Boolean disallowgreaterthan; // CExpr2.c @@ -174,7 +176,7 @@ extern void CExpr_MatchCV(Type *t1, UInt32 q1, Type *t2, UInt32 q2, Match13 *mat extern Boolean CExpr_MatchAssign(Type *type, UInt32 qual, ENode *expr, Match13 *match); extern ENode *CExpr_ClassPointerCast(BClassList *cls, ENode *expr, Boolean nullcheckflag); extern ENode *CExpr_GetClassAccessNode(BClassList *a, BClassList *b, ENode *expr, Object *obj, AccessType access, Boolean flag); -extern ENode *CExpr_ConvertToBool(ENode *expr, Boolean flag); +extern ENode *CExpr_ConvertToBool(ENode *expr, Boolean isExplicit); extern void CExpr_ConversionIteratorInit(ConversionIterator *iter, TypeClass *tclass); extern Object *CExpr_ConversionIteratorNext(ConversionIterator *iter); extern short user_assign_check(ENode *expr, Type *type, UInt32 qual, Boolean flag1, Boolean flag2, Boolean flag3); @@ -197,45 +199,12 @@ extern ENode *scannew(Boolean flag); extern ENode *scandelete(Boolean flag); // CExprConvMatch.c -// static void CExpr_GetImplictObjectParamType(); -// static void CExpr_GetParamType(); -// static void CExpr_HasNParams(); -// static void CExpr_TypeCompare(); -// static void CExpr_IsReferenceCompatible(); -// static void CExpr_IsBaseOf(); -// static void CExpr_IsBetterClassConversion(); -// static void CExpr_IsBetterStandardConv(); -// static void CExpr_IsBetterImplicitConv(); -// static void CExpr_SetupStandardConversionResult(); -// static void CExpr_SetQualConversionResult(); -// static void CExpr_OverloadFuncMatch(); -// static void CExpr_StandardConversionMatch(); -// static void CExpr_UserConversion(); -// static void CExpr_UserConversionMatch(); -// static void CExpr_ImplicitConversionMatch(); -extern Boolean CExpr_CanImplicitlyConvert(ENode *expr, Type *type, UInt32 qual); -// static void CExpr_DerivedToBase(); -// static void CExpr_ClassReferenceConversion(); -// static void CExpr_BindToReference(); -extern ENode *CExpr_Convert(ENode *expr, Type *type, UInt32 qual, Boolean flag1, Boolean flag2); -extern ENode *CExpr_AssignmentPromotion(ENode *expr, Type *type, UInt32 qual, Boolean flag); -// static void CExpr_IsBetterMatch(); -// static void CExpr_MatchArgs(); -// static void CExpr_GetMatchObject(); -// static void CExpr_FindBestMatch(); -extern void CExpr_FuncArgMatch(NameSpaceObjectList *nsol, TemplArg *templargs, ENodeList *argexprs, Match13 *match, ENode *expr, Boolean flag); -// static void CExpr_BuildConversionTypeList(); -// static void CExpr_NextPromotedIntegralType(); -// static void CExpr_NextArithmeticType(); -// static void CExpr_NextPromotedArithmeticType(); -// static void CExpr_MatchBuiltin(); -// static void CExpr_CheckIncDecBuiltin(); -// static void CExpr_CheckUnaryBuiltin(); -// static void CExpr_CheckBinaryBuiltin(); -// static void CExpr_MatchOperands(); +extern Boolean CExpr_CanImplicitlyConvert(ENode *expr, Type *type2, UInt32 qual2); +extern ENode *CExpr_Convert(ENode *expr, Type *type, UInt32 qual, Boolean isExplicit, Boolean flag2); +extern ENode *CExpr_AssignmentPromotion(ENode *expr, Type *type2, UInt32 qual2, Boolean flag); +extern void CExpr_FuncArgMatch(NameSpaceObjectList *list, TemplArg *templargs, ENodeList *argexprs, Match13 *match13, ENode *expr, Boolean flag); extern Boolean CExpr_CondOperatorMatch(ENode *left, ENode *right, Conversion *conv); extern Boolean CExpr_OperatorMatch(short token, ENode *left, ENode *right, Conversion *conv); -// static void CExpr_ClassCopyInit(); #ifdef __MWERKS__ #pragma options align=reset diff --git a/includes/compiler/CFunc.h b/includes/compiler/CFunc.h index bed511f..a64cc74 100644 --- a/includes/compiler/CFunc.h +++ b/includes/compiler/CFunc.h @@ -49,6 +49,7 @@ typedef enum StatementType { enum { StmtFlag_1 = 1, StmtFlag_2 = 2, + StmtFlag_4 = 4, StmtFlag_8 = 8, StmtFlag_10 = 0x10 }; @@ -80,9 +81,15 @@ typedef struct InitExpr { Object *object; } InitExpr; +typedef enum CtorChainType { + CtorChain_Base = 0, + CtorChain_VBase = 1, + CtorChain_MemberVar = 2 +} CtorChainType; + typedef struct CtorChain { struct CtorChain *next; - UInt8 what; + CtorChainType what; ENode *objexpr; union { ClassList *base; // 0 @@ -91,17 +98,19 @@ typedef struct CtorChain { } u; } CtorChain; -typedef struct CFuncSave { - CScopeSave scope; - // lots of fields -} CFuncSave; +typedef struct CFuncSave CFuncSave; struct DeclThing { Type *thetype; UInt32 qual; - NameSpace *nspace; - CLabel *xC; - CLabel *x10; + SwitchInfo *switchinfo; + CLabel *loopContinue; + CLabel *loopBreak; +}; + +struct DefArgCtorInfo { + Object *default_func; + ENode *default_arg; }; extern FuncArg elipsis; @@ -122,7 +131,7 @@ extern Statement *curstmt; extern DeclBlock *CFunc_NewDeclBlock(void); extern void CFunc_RestoreBlock(DeclBlock *block); extern void CFunc_SetupLocalVarInfo(Object *obj); -extern void CFunc_DefaultArg(Type *type, short qual, FuncArg *args); +extern ENode *CFunc_DefaultArg(Type *type, UInt32 qual, FuncArg *args); extern Boolean CFunc_ParseFakeArgList(Boolean flag); extern FuncArg *parameter_type_list(DeclInfo *declinfo); extern CLabel *findlabel(void); @@ -137,19 +146,19 @@ extern ENode *create_temp_node2(Type *type); extern void CFunc_WarnUnused(void); extern void CFunc_CodeCleanup(Statement *stmt); extern void CFunc_DestructorCleanup(Statement *stmt); -extern Statement *CFunc_GenerateLoop(Statement *stmt, Type *type, ENode *expr1, ENode *expr2, ENode *expr3, ENode *expr4, ENode (*callback)(ENode *, ENode *)); +extern Statement *CFunc_GenerateLoop(Statement *stmt, Type *type, ENode *lowerBound, ENode *upperBound, ENode *increment1, ENode *increment2, ENode *(*callback)(ENode *, ENode *)); extern void CFunc_CompoundStatement(DeclThing *thing); -extern void CFunc_SetupNewFuncArgs(Object *obj, FuncArg *args); +extern void CFunc_SetupNewFuncArgs(Object *func, FuncArg *args); extern NameSpace *CFunc_FuncGenSetup(Statement *stmt, Object *func); -extern void CFunc_GetGlobalCompilerState(CFuncSave *state); +extern CFuncSave *CFunc_GetGlobalCompilerState(void); extern void CFunc_SetGlobalCompilerState(CFuncSave *state); -extern void CFunc_Gen(Statement *stmt, Object *obj, UInt8 unk); +extern void CFunc_Gen(Statement *stmt, Object *func, UInt8 unk); extern void CFunc_CheckClassCtors(TypeClass *tclass); -extern void CFunc_ParseFuncDef(Object *obj, DeclInfo *declinfo, TypeClass *tclass, Boolean is_method, Boolean is_static, NameSpace *nspace); +extern void CFunc_ParseFuncDef(Object *func, DeclInfo *di, TypeClass *tclass, Boolean is_method, Boolean is_static, NameSpace *nspace); extern void InitExpr_Register(ENode *expr, Object *object); -extern void CFunc_GenerateDummyFunction(Object *a); -extern void CFunc_GenerateSingleExprFunc(Object *a, ENode *expr); -extern void CFunc_GenerateDummyCtorFunc(Object *a, Object *b); +extern void CFunc_GenerateDummyFunction(Object *func); +extern void CFunc_GenerateSingleExprFunc(Object *func, ENode *expr); +extern void CFunc_GenerateDummyCtorFunc(Object *func, Object *real_ctor); #ifdef __MWERKS__ #pragma options align=reset diff --git a/includes/compiler/CInit.h b/includes/compiler/CInit.h index e6e3d61..dc5d759 100644 --- a/includes/compiler/CInit.h +++ b/includes/compiler/CInit.h @@ -10,8 +10,7 @@ typedef void (*ExprCB)(Type *type, ENode *expr, Boolean flag); typedef void (*InitExprRegisterCB)(ENode *expr); typedef void (*InsertExprCB)(ENode *expr); -// fix last arg -typedef ENode *(*RegisterObjectCB)(Type *type, Object *obj, SInt32 offset, void *); +typedef ENode *(*RegisterObjectCB)(Type *type, Object *obj, SInt32 offset, Boolean flag); typedef ENode *(*TempNodeCB)(Type *type, Boolean flag); struct OLinkList { diff --git a/includes/compiler/CInline.h b/includes/compiler/CInline.h index 52cdf13..4fae90a 100644 --- a/includes/compiler/CInline.h +++ b/includes/compiler/CInline.h @@ -9,6 +9,22 @@ #pragma options align=mac68k #endif +// Not sure if these two are actually in CInline or not +typedef struct XRefOffset { + UInt32 xrefoffset; + SInt32 offset; +} XRefOffset; + +struct InlineXRef { + InlineXRef *next; + Object *object; + UInt16 xrefmode; + UInt16 numxrefs; + XRefOffset xref[1]; +}; + + + typedef struct CI_Var { HashNameNode *name; Type *type; @@ -33,10 +49,10 @@ typedef struct CI_SwitchCase { typedef struct CI_Switch { ENode *expr; - void *unkSwitch8; + Type *unkSwitch8; short defaultlabelID; short numcases; - CI_SwitchCase cases[0]; + CI_SwitchCase cases[1]; } CI_Switch; typedef struct CI_Statement { diff --git a/includes/compiler/CMangler.h b/includes/compiler/CMangler.h index f08ecd8..2e84032 100644 --- a/includes/compiler/CMangler.h +++ b/includes/compiler/CMangler.h @@ -17,15 +17,15 @@ extern HashNameNode *CMangler_VBaseDtorName(void); extern HashNameNode *CMangler_ArrayDtorName(void); extern HashNameNode *CMangler_SDeleteDtorName(void); extern HashNameNode *CMangler_DeleteDtorName(void); -extern char *CMangler_GetOperator(HashNameNode *opname); +extern char *CMangler_GetOperator(HashNameNode *name); extern HashNameNode *CMangler_OperatorName(short token); -extern HashNameNode *CMangler_VTableName(TypeClass *tclass); +extern HashNameNode *CMangler_VTableName(TypeClass *theclass); extern HashNameNode *CMangler_RTTIObjectName(Type *type, UInt32 qual); -extern HashNameNode *CMangler_ThunkName(Object *obj, int a, int b, int c); +extern HashNameNode *CMangler_ThunkName(Object *vfunc, SInt32 this_delta, SInt32 return_delta, SInt32 ctoroffset); extern HashNameNode *CMangler_TemplateInstanceName(HashNameNode *basename, TemplArg *args); extern void CMangler_MangleType(Type *type, UInt32 qual); extern HashNameNode *CMangler_ConversionFuncName(Type *type, UInt32 qual); -extern HashNameNode *CMangler_GetCovariantFunctionName(Object *obj, Type *type); +extern HashNameNode *CMangler_GetCovariantFunctionName(Object *dobj, TypeClass *theclass); extern HashNameNode *CMangler_GetLinkName(Object *obj); #ifdef __MWERKS__ diff --git a/includes/compiler/CParser.h b/includes/compiler/CParser.h index 5d9a67a..7312e33 100644 --- a/includes/compiler/CParser.h +++ b/includes/compiler/CParser.h @@ -77,7 +77,7 @@ typedef struct COpts { Boolean altivec_model; UInt8 altivec_vrsave; UInt8 code_alignment; - char x1D; + UInt8 x1D; UInt8 x1E; // some register used in TOC_use_isel UInt8 gen_fsel; Boolean ppc_opt_bclr_bcctr; @@ -99,7 +99,7 @@ typedef struct COpts { Boolean objective_c; Boolean objc_strict; Boolean ARM_conform; - char ARM_scoping; + Boolean ARM_scoping; Boolean require_prototypes; Boolean trigraphs; Boolean only_std_keywords; @@ -130,14 +130,14 @@ typedef struct COpts { Boolean flat_include; char syspath_once; Boolean always_import; - char simple_class_byval; + Boolean simple_class_byval; Boolean wchar_type; Boolean vbase_ctor_offset; - char vbase_abi_v2; + Boolean vbase_abi_v2; Boolean def_inherited; Boolean template_patch; char template_friends; - char faster_pch_gen; + Boolean faster_pch_gen; Boolean array_new_delete; Boolean dollar_identifiers; char def_inline_tfuncs; @@ -146,7 +146,7 @@ typedef struct COpts { Boolean line_prepdump; Boolean fullpath_prepdump; char old_mtemplparser; - char suppress_init_code; + Boolean suppress_init_code; Boolean reverse_bitfields; Boolean c9x; Boolean float_constants; @@ -166,15 +166,15 @@ typedef struct COpts { char microsoft; Boolean warningerrors; Boolean pedantic; - char check_header_flags; + Boolean check_header_flags; Boolean supress_warnings; Boolean warn_illpragma; Boolean warn_emptydecl; Boolean warn_possunwant; - char warn_unusedvar; - char warn_unusedarg; + Boolean warn_unusedvar; + Boolean warn_unusedarg; Boolean warn_extracomma; - char warn_hidevirtual; + Boolean warn_hidevirtual; Boolean warn_largeargs; Boolean warn_implicitconv; Boolean warn_notinlined; @@ -182,7 +182,7 @@ typedef struct COpts { Boolean warn_padding; Boolean warn_no_side_effect; Boolean warn_resultnotused; - char warn_ptr_int_conv; + Boolean warn_ptr_int_conv; char align_mode; Boolean align_array_members; Boolean dont_reuse_strings; @@ -208,16 +208,16 @@ typedef struct COpts { Boolean crippled; Boolean opt_common_subs; Boolean opt_loop_invariants; - char opt_propagation; - char opt_dead_assignments; + Boolean opt_propagation; + Boolean opt_dead_assignments; Boolean opt_strength_reduction; Boolean opt_strength_reduction_strict; - char opt_dead_code; - char opt_lifetimes; + Boolean opt_dead_code; + Boolean opt_lifetimes; char _B1; // unused? - char opt_unroll_loops; + Boolean opt_unroll_loops; char opt_vectorize_loops; - char _B4; // amount of IRO passes? + Boolean _B4; // amount of IRO passes? Boolean opt_pointer_analysis; unsigned char opt_pointer_analysis_mode; char loop_unroll_count; @@ -386,8 +386,8 @@ extern Boolean is_const_object(Object *obj); extern Boolean is_volatile_object(Object *obj); extern Boolean CParserIsConstExpr(ENode *expr); extern Boolean CParserIsVolatileExpr(ENode *expr); -extern Boolean CParser_HasInternalLinkage(Object *obj); -extern Boolean CParser_HasInternalLinkage2(Object *obj); +extern Boolean CParser_HasInternalLinkage(const Object *obj); +extern Boolean CParser_HasInternalLinkage2(const Object *obj); extern Boolean CParser_IsVirtualFunction(Object *obj, TypeClass **tclass, SInt32 *index); extern Boolean is_pascal_object(Object *obj); extern Boolean is_cfm_type(Type *type); diff --git a/includes/compiler/CPrec.h b/includes/compiler/CPrec.h new file mode 100644 index 0000000..a2ac87c --- /dev/null +++ b/includes/compiler/CPrec.h @@ -0,0 +1,12 @@ +#ifndef COMPILER_CPREC_H +#define COMPILER_CPREC_H + +#include "compiler/common.h" + +extern void SetupPrecompiler(void); +extern void CleanupPrecompiler(void); +extern void PreComp_StaticData(Object *obj, const void *data, OLinkList *links, SInt32 size); +extern void PrecompilerWrite(void); +extern void PrecompilerRead(short refnum, void *buffer); + +#endif diff --git a/includes/compiler/CPrep.h b/includes/compiler/CPrep.h index e9b7dcd..aeb341b 100644 --- a/includes/compiler/CPrep.h +++ b/includes/compiler/CPrep.h @@ -11,11 +11,11 @@ struct Macro { Macro *next; HashNameNode *name; - void *c; + char *c; unsigned short xC; Boolean is_special; Boolean xF; - void *e; + HashNameNode *names[1]; }; typedef struct TokenStack { char *pos; @@ -71,6 +71,7 @@ extern CPrepFileInfo *prep_file; extern short filesp; extern SInt32 linenumber; extern struct GList pplist; +extern TStreamElement *ts_last; extern TStreamElement *ts_current; extern SInt32 ts_preread_elements; diff --git a/includes/compiler/CPrepTokenizer.h b/includes/compiler/CPrepTokenizer.h index f65cff6..d6ea7c3 100644 --- a/includes/compiler/CPrepTokenizer.h +++ b/includes/compiler/CPrepTokenizer.h @@ -10,13 +10,13 @@ extern short prepskipnextchar(void); extern short prepnextchar(void); -extern short prepnextstringchar(char *str, Boolean flag); +extern short prepnextstringchar(StringPtr str, Boolean flag); extern void CPrep_MatchChar(char ch, Boolean flag); extern char *CPrep_MatchChar2(char *start, char ch, Boolean flag); extern short prepcurchar(void); -extern char *ReadIdentifier(char *p); -extern char *CPrep_SkipNewComment(char *str); -extern Boolean skipendoflinematch(char *str, short token); +extern char *ReadIdentifier(const char *p); +extern StringPtr CPrep_SkipNewComment(StringPtr str); +extern Boolean skipendoflinematch(StringPtr str, short token); extern void skipendofline(void); extern void CPrep_SkipAsmComment(void); extern short lookahead(void); diff --git a/includes/compiler/CScope.h b/includes/compiler/CScope.h index a1da819..f9ba72c 100644 --- a/includes/compiler/CScope.h +++ b/includes/compiler/CScope.h @@ -57,7 +57,7 @@ extern void CScope_SetNameSpaceScope(NameSpace *nspace, CScopeSave *save); extern void CScope_SetClassScope(TypeClass *cls, CScopeSave *save); extern void CScope_SetClassDefScope(TypeClass *cls, CScopeSave *save); extern void CScope_SetFunctionScope(Object *function, CScopeSave *save); -extern void CScope_SetMethodScope(Object *function, TypeClass *cls, Boolean unknownFlag, CScopeSave *save); +extern void CScope_SetMethodScope(Object *function, TypeClass *cls, Boolean is_static, CScopeSave *save); extern void CScope_RestoreScope(CScopeSave *saved); extern Boolean CScope_IsEmptySymTable(void); extern Boolean CScope_IsInLocalNameSpace(NameSpace *nspace); diff --git a/includes/compiler/CodeGen.h b/includes/compiler/CodeGen.h index 1f012ec..46fe8fc 100644 --- a/includes/compiler/CodeGen.h +++ b/includes/compiler/CodeGen.h @@ -65,7 +65,7 @@ extern SInt32 CodeGen_objc_method_arg_offset(ObjCMethod *meth, ObjCMethodArg *ar extern SInt32 CodeGen_objc_method_args_size(ObjCMethod *meth); extern ENode *CodeGen_HandleIntrinsicCall(Object *func, ENodeList *arg_exprs); extern ENode *CodeGen_HandleTypeCast(ENode *expr, Type *type, UInt32 qual); -extern short CodeGen_AssignCheck(ENode *expr, Type *type, Boolean flag1, Boolean flag2); +extern short CodeGen_AssignCheck(const ENode *expr, const Type *type, Boolean flag1, Boolean flag2); extern Boolean CodeGen_CollapseVectorExpression(ENode *expr, MWVector128 *vec, Type *type); extern void CodeGen_InsertSpecialMacros(void); extern char *CodeGen_ExpandSpecialMacro(Macro *macro); diff --git a/includes/compiler/CompilerTools.h b/includes/compiler/CompilerTools.h index d44d766..82ef228 100644 --- a/includes/compiler/CompilerTools.h +++ b/includes/compiler/CompilerTools.h @@ -128,7 +128,7 @@ extern UInt32 CTool_EndianReadWord32(void *ptr); #define CTool_EndianConvertWord32(value) value #define CTool_EndianConvertWord16(value) value #define CTool_EndianConvertMem(data, len) ((void)0) -#define CTool_EndianReadWord32(ptr) (*((UInt32 *) (ptr))) +#define CTool_EndianReadWord32(ptr) (*((SInt32 *) (ptr))) #endif extern void CTool_EndianConvertWord64(CInt64 ci, char *result); extern UInt16 CTool_EndianConvertInPlaceWord16Ptr(UInt16 *x); diff --git a/includes/compiler/Exceptions.h b/includes/compiler/Exceptions.h index cc485b0..01efcde 100644 --- a/includes/compiler/Exceptions.h +++ b/includes/compiler/Exceptions.h @@ -143,10 +143,10 @@ typedef struct PCAction { extern EANode *DAG[EAT_NACTIONS]; +extern void initializeexceptiontables(void); extern int countexceptionactionregisters(ExceptionAction *actions); extern void noteexceptionactionregisters(ExceptionAction *actions, PCodeArg *ops); extern void recordexceptionactions(PCode *instr, ExceptionAction *actions); -extern void deleteexceptionaction(PCAction *pca); extern void dumpexceptiontables(Object *function, SInt32 codesize); #endif diff --git a/includes/compiler/GCCInlineAsm.h b/includes/compiler/GCCInlineAsm.h index 0b61384..18e24d0 100644 --- a/includes/compiler/GCCInlineAsm.h +++ b/includes/compiler/GCCInlineAsm.h @@ -3,7 +3,7 @@ #include "compiler/common.h" -extern void InlineAsm_SkipComment(); +extern void InlineAsm_SkipComment(void); extern void InlineAsm_gcc_parse(void); extern Statement *first_ST_ASM; diff --git a/includes/compiler/InlineAsm.h b/includes/compiler/InlineAsm.h index ba92400..ca0032e 100644 --- a/includes/compiler/InlineAsm.h +++ b/includes/compiler/InlineAsm.h @@ -160,6 +160,11 @@ typedef struct IAEffect { SInt32 size; } IAEffect; +enum { + IAMaxOperands = 16, + IAMaxLabels = 16 +}; + typedef struct IAEffects { Boolean x0; Boolean x1; @@ -169,8 +174,8 @@ typedef struct IAEffects { Boolean x5; SInt32 numoperands; SInt32 numlabels; - IAEffect operands[16]; - CLabel *labels[16]; + IAEffect operands[IAMaxOperands]; + CLabel *labels[IAMaxLabels]; } IAEffects; #ifdef __MWERKS__ diff --git a/includes/compiler/InlineAsmPPC.h b/includes/compiler/InlineAsmPPC.h index a3d8655..d20bb42 100644 --- a/includes/compiler/InlineAsmPPC.h +++ b/includes/compiler/InlineAsmPPC.h @@ -4,6 +4,16 @@ #include "compiler/common.h" #include "compiler/InlineAsm.h" +typedef enum AssemblerType { + AssemblerType_0, + AssemblerType_1 +} AssemblerType; + +enum { + NO_REG = 0, + INVALID_PIC_REG = -2 +}; + extern char asm_alloc_flags[10]; extern Section sm_section; extern UInt32 cpu; @@ -11,7 +21,7 @@ extern SInt32 fralloc_parameter_area_size; extern Boolean user_responsible_for_frame; extern Boolean supports_hardware_fpu; extern UInt32 assembledinstructions; -extern UInt8 assembler_type; +extern AssemblerType assembler_type; extern char volatileasm; extern Boolean InlineAsm_gccmode; extern Boolean InlineAsm_labelref; @@ -68,8 +78,8 @@ enum { }; extern void InlineAsm_InitializePPC(void); -extern void InlineAsm_Initialize(UInt8 assemblertype); -extern SInt32 InlineAsm_IsDirective(UInt8 assemblertype); +extern void InlineAsm_Initialize(AssemblerType assemblertype); +extern SInt32 InlineAsm_IsDirective(AssemblerType assemblertype); extern void InlineAsm_ProcessDirective(SInt32 directive); extern void InlineAsm_ScanAssemblyDirective(void); extern void InlineAsm_ScanAssemblyInstruction(void); diff --git a/includes/compiler/IrOptimizer.h b/includes/compiler/IrOptimizer.h index 2061a5d..287e279 100644 --- a/includes/compiler/IrOptimizer.h +++ b/includes/compiler/IrOptimizer.h @@ -22,7 +22,7 @@ extern Boolean IRO_CPFirstTime; extern Boolean VectorPhaseCalledFromUnroll; extern Boolean IRO_Log; -extern Statement *IRO_Optimizer(Object *obj, Statement *stmt); +extern Statement *IRO_Optimizer(Object *func, Statement *statements); extern void IRO_Setup(void); extern void IRO_Cleanup(void); extern void CodeGen_UpdateOptimizerOptions(void); diff --git a/includes/compiler/IroEval.h b/includes/compiler/IroEval.h index 9a4b2bf..a011a47 100644 --- a/includes/compiler/IroEval.h +++ b/includes/compiler/IroEval.h @@ -3,8 +3,12 @@ #include "compiler/IrOptimizer.h" -// TODO -extern void IRO_TruncateBitfieldValueToType(CInt64 *val, Type *type, Type *type2); +extern void IRO_InitializeIsAssociativeENodeTypeArray(void); extern void IRO_TruncateValueToType(CInt64 *val, Type *type); +extern void IRO_TruncateBitfieldValueToType(CInt64 *val, Type *type, Type *type2); +extern void IRO_ConstantFolding(void); +extern Boolean IRO_EvaluateConditionals(void); +extern int IRO_SimplifyConditionals(void); +extern Boolean IRO_EvaluateDefinitePointers(Object *func); #endif diff --git a/includes/compiler/IroLinearForm.h b/includes/compiler/IroLinearForm.h index 6ba0021..1e7df4f 100644 --- a/includes/compiler/IroLinearForm.h +++ b/includes/compiler/IroLinearForm.h @@ -157,7 +157,9 @@ extern void IRO_RestoreLinearIR(IROLinearIRSave *save); #define IS_LINEAR_ENODE(_linear, _nodetype) ( ((_linear)->type == IROLinearOperand) && ((_linear)->u.node->type) == (_nodetype) ) #define IS_LINEAR_MONADIC(_linear, _nodetype) ( ((_linear)->type == IROLinearOp1Arg) && ((_linear)->nodetype) == (_nodetype) ) +#define IS_LINEAR_MONADIC_2(_linear, _nodetype1, _nodetype2) ( ((_linear)->type == IROLinearOp1Arg) && (((_linear)->nodetype) == (_nodetype1) || ((_linear)->nodetype) == (_nodetype2)) ) #define IS_LINEAR_DIADIC(_linear, _nodetype) ( ((_linear)->type == IROLinearOp2Arg) && ((_linear)->nodetype) == (_nodetype) ) #define IS_LINEAR_DIADIC_2(_linear, _nodetype1, _nodetype2) ( ((_linear)->type == IROLinearOp2Arg) && (((_linear)->nodetype) == (_nodetype1) || ((_linear)->nodetype) == (_nodetype2)) ) +#define IS_LINEAR_DIADIC_3(_linear, _nodetype1, _nodetype2, _nodetype3) ( ((_linear)->type == IROLinearOp2Arg) && (((_linear)->nodetype) == (_nodetype1) || ((_linear)->nodetype) == (_nodetype2) || ((_linear)->nodetype) == (_nodetype3)) ) #endif diff --git a/includes/compiler/IroLoop.h b/includes/compiler/IroLoop.h index 8357830..0c60589 100644 --- a/includes/compiler/IroLoop.h +++ b/includes/compiler/IroLoop.h @@ -5,32 +5,32 @@ #include "compiler/BitVector.h" typedef enum IROLoopIndFlags { - LoopInd_1 = 1, - LoopInd_2 = 2, + LoopInd_HasMod = 1, + LoopInd_HasDiv = 2, LoopInd_4 = 4, LoopInd_8 = 8 } IROLoopIndFlags; typedef enum IROLoopFlags { - LoopFlags_1 = 1, + LoopFlags_1 = 1, // LP_INDUCTION_AT_LEFT LP_LOOP_HAS_CALLS = 2, LP_LOOP_HAS_CNTRLFLOW = 4, - LoopFlags_8 = 8, + LoopFlags_8 = 8, // LP_HAS_NONASSIGN LP_INDUCTION_NOT_FOUND = 0x10, LP_IFEXPR_NON_CANONICAL = 0x20, LP_HAS_MULTIPLE_INDUCTIONS = 0x40, LP_LOOP_HDR_HAS_SIDEEFFECTS = 0x80, - LoopFlags_100 = 0x100, - LoopFlags_200 = 0x200, + LP_LOOP_STEP_ISADD = 0x100, + LoopFlags_200 = 0x200, // LP_HEADER_FOLLOWS_UPDATE? LP_LOOP_STEP_ISPOS = 0x400, - LoopFlags_800 = 0x800, - LoopFlags_1000 = 0x1000, - LoopFlags_2000 = 0x2000, + LoopFlags_800 = 0x800, // LP_IND_USED_IN_LOOP + LoopFlags_1000 = 0x1000, // LP_HAS_MULTIPLE_EXITS + LoopFlags_2000 = 0x2000, // inverse of LP_LOOP_STEP_ISADD? LP_LOOP_STEP_ISNEG = 0x4000, LP_LOOP_HAS_ASM = 0x8000, - LoopFlags_10000 = 0x10000, - LoopFlags_20000 = 0x20000, - LoopFlags_40000 = 0x40000 + LoopFlags_10000 = 0x10000, // LP_WHILE_LOOP + LoopFlags_20000 = 0x20000, // maybe LP_RECURSIVE_LOOP? + LoopFlags_40000 = 0x40000 // LP_IS_REDUCTION_CAND } IROLoopFlags; #ifdef __MWERKS__ @@ -50,10 +50,10 @@ struct IROLoop { SInt32 flags; IRONode *fnode; int x8; - int xC; - int x10; + IRONode *xC; + IRONode *x10; IROLinear *nd14; // assignment expression that sets the initial value of induction - IROLinear *nd18; + IROLinear *nd18; // ifexpr? IROLoopInd *induction; int index20; int index24; diff --git a/includes/compiler/IroPointerAnalysis.h b/includes/compiler/IroPointerAnalysis.h index 3266047..a6ed2c2 100644 --- a/includes/compiler/IroPointerAnalysis.h +++ b/includes/compiler/IroPointerAnalysis.h @@ -13,7 +13,7 @@ extern Boolean PointerAnalysis_IsENodePointerExprDefinite(Object *proc, ENode *n extern Boolean PointerAnalysis_IsVariableValueDefinite(Object *proc, VarRecord *var, PointsToFunction *pointsTo); extern void PointerAnalysis_LookupLinearNodePointerExpr(Object *proc, IROLinear *indirect, IROListNode **list); extern void PointerAnalysis_LookupENodePointerExpr(Object *proc, ENode *indirect, ENodeList **list); -extern void PointerAnalysis_LookupVariableIntoLinearNodeExprs(Object *proc, VarRecord *var, PointsToFunction *pointsTo, IROList **list); +extern void PointerAnalysis_LookupVariableIntoLinearNodeExprs(Object *proc, VarRecord *var, PointsToFunction *pointsTo, IROListNode **list); extern void PointerAnalysis_LookupVariableIntoENodeExprs(Object *proc, VarRecord *var, PointsToFunction *pointsTo, ENodeList **list); extern void PointerAnalysis_GetFunctionKills(Object *proc, IROLinear *funccall, ObjectList **list); extern void PointerAnalysis_GetFunctionDependencies(Object *proc, IROLinear *funccall, ObjectList **list); diff --git a/includes/compiler/IroTransform.h b/includes/compiler/IroTransform.h index 0ec4f4c..90bcf30 100644 --- a/includes/compiler/IroTransform.h +++ b/includes/compiler/IroTransform.h @@ -3,7 +3,11 @@ #include "compiler/IrOptimizer.h" -// TODO -extern Boolean IRO_TransformSelfAssignmentToAssignment(IROLinear *linear); +extern void IRO_InitializeAssignmentOpArray(void); +extern void IRO_InitializeComplementaryOpArray(void); +extern void IRO_InitializeComplementaryOpLogicalArray(void); +extern void IRO_DoTransformations(void); +extern Boolean IRO_TransformSelfAssignmentToAssignment(IROLinear *nd); +extern void IRO_TransformTree(Statement *statements); #endif diff --git a/includes/compiler/IroUnrollLoop.h b/includes/compiler/IroUnrollLoop.h index 9e08d03..8a51a9b 100644 --- a/includes/compiler/IroUnrollLoop.h +++ b/includes/compiler/IroUnrollLoop.h @@ -2,21 +2,22 @@ #define COMPILER_IROUNROLLLOOP_H #include "compiler/IrOptimizer.h" +#include "compiler/IroLinearForm.h" extern void IRO_LoopUnroller(void); -extern void IRO_IterateForLoopBody(); -extern void IRO_LinearizeForLoopPostLoop(); -extern void BuildEarlyLoopExitTest(); -extern void BuildLoopExitTest(); -extern void IsIterationCountConstant(); -extern void NoOpBlock(); -extern void IRO_TestConstantIterationCount(); -extern void BuildOrigIterationCount(); -extern void BuildNewFinalvalue(); -extern void BuildUnrolledBodyEntryTest(); -extern void ChangeInductionReference(); -extern void UpdateInductionIncrement(); -extern void GenInitialAssignment(); -extern void GenNewInduction(); +extern void IRO_IterateForLoopBody(IRONode *start, IRONode *end, IROLoop *loop, IROLinear *destnode, SInt32 addConst, CInt64 *val, Boolean funkyFlag); +extern void IRO_LinearizeForLoopPostLoop(IRONode *fnode1, IRONode *fnode2, IROLoop *loop, IRONode *fnode3, UInt32 unrollFactor); +extern IROLinear *BuildEarlyLoopExitTest(IROLinearType type, IROList *list); +extern IROLinear *BuildLoopExitTest(IROLinearType type, IROList *list); +extern int IsIterationCountConstant(IROLoop *loop, CInt64 *pval); +extern void NoOpBlock(IRONode *fnode); +extern void IRO_TestConstantIterationCount(IROLoop *loop, CInt64 *iterCount, SInt32 vectorStride, UInt32 *unrollFactor, SInt32 *leftOver, UInt32 *needOrigLoop, UInt32 *needUnrollBodyTest, UInt32 *resetUnrolledFinalValue); +extern IROLinear *BuildOrigIterationCount(IROList *list, IROLoop *loop); +extern IROLinear *BuildNewFinalvalue(IROLinear *iterCount, UInt32 unrollFactor, IROList *list, IROLoop *loop); +extern void BuildUnrolledBodyEntryTest(IROList *list, IROLinear *iterCount, UInt32 unrollFactor, CLabel *label); +extern void ChangeInductionReference(IROLinear *first, IROLinear *last, CInt64 val, IROLoop *loop); +extern IROLinear *UpdateInductionIncrement(IROLoop *loop, SInt32 value, IROLinear *before); +extern void GenInitialAssignment(IROLoop *loop, Object *var, IROList *list); +extern void GenNewInduction(void); #endif diff --git a/includes/compiler/IroUtil.h b/includes/compiler/IroUtil.h index 68d34f5..502d0cd 100644 --- a/includes/compiler/IroUtil.h +++ b/includes/compiler/IroUtil.h @@ -2,6 +2,7 @@ #define COMPILER_IROUTIL_H #include "compiler/IrOptimizer.h" +#include "compiler/CInt64.h" #include "compiler/CParser.h" #ifdef __MWERKS__ @@ -87,7 +88,7 @@ extern IROLinear *IRO_LocateFather_Cut_And_Paste(IROLinear *a, IROLinear *b); extern IROLinear *IRO_LocateFather_Cut_And_Paste_Without_Nopping(IROLinear *a, IROLinear *b); extern void IRO_ReplaceReference(IROLinear *a, Object *obj, IROLinear *b); extern void IRO_ReplaceReferenceWithNode(IROLinear *a, IROLinear *b); -extern void IRO_GetTemp(IROExpr *expr); +extern VarRecord *IRO_GetTemp(IROExpr *expr); extern IROLinear *IRO_AssignToTemp(IROExpr *expr); extern IROLinear *IRO_FindStart(IROLinear *linear); extern void IRO_DeleteCommaNode(IROLinear *linear, IROExpr *expr); @@ -99,7 +100,7 @@ typedef void (*WalkObjFunc)(Object *obj); extern void IRO_WalkExcActions(ExceptionAction *action, WalkObjFunc func); extern Boolean IRO_FunctionCallMightThrowException(IROLinear *linear); extern IROLinear *IRO_NewIntConst(CInt64 val, Type *type); -extern IROLinear *IRO_NewFloatConst(Float val, Type *type); +extern IROLinear *IRO_NewFloatConst(const Float val, Type *type); extern Boolean IRO_IsAddressMultiply(IROLinear *linear); extern void IRO_SetupForUserBreakChecking(void); extern void IRO_CheckForUserBreak(void); @@ -109,4 +110,18 @@ inline Boolean IRO_IsUnsignedType(Type *type) { return is_unsigned(type); } +// 4B4D40 +inline CInt64 IRO_MakeULong(UInt32 i) { + CInt64 val; + CInt64_SetULong(&val, i); + return val; +} + +// 4BAAA0 +inline CInt64 IRO_MakeLong(SInt32 i) { + CInt64 val; + CInt64_SetLong(&val, i); + return val; +} + #endif diff --git a/includes/compiler/LoopDetection.h b/includes/compiler/LoopDetection.h index 28dbb7a..5d9a729 100644 --- a/includes/compiler/LoopDetection.h +++ b/includes/compiler/LoopDetection.h @@ -86,7 +86,7 @@ typedef struct InductionVar { extern Loop *loopsinflowgraph; extern int loopdetection_nblocks; extern BitVector *LoopTemp; -extern void *LoopList_First; +extern struct LoopList *LoopList_First; extern void addblocktoloop(Loop *loop, PCodeBlock *block); extern void insertpreheaderblock(Loop *loop); diff --git a/includes/compiler/PCode.h b/includes/compiler/PCode.h index b38d9e1..9b6103b 100644 --- a/includes/compiler/PCode.h +++ b/includes/compiler/PCode.h @@ -198,17 +198,18 @@ enum { }; enum { - fPCBlockFlag1 = 1, // prologue - fPCBlockFlag2 = 2, // epilogue - fPCBlockFlag4 = 4, - fPCBlockFlag8 = 8, // scheduled? - fPCBlockFlag10 = 0x10, - fPCBlockFlag20 = 0x20, + fPCBlockFlag1 = 1, // fIsProlog + fPCBlockFlag2 = 2, // fIsEpilogue + fPCBlockFlag4 = 4, // fVisited + fPCBlockFlag8 = 8, // fScheduled + fPCBlockFlag10 = 0x10, // maybe fIsSwitch based off v3? + fPCBlockFlag20 = 0x20, // fDeleted fPCBlockFlag2000 = 0x2000, fPCBlockFlag4000 = 0x4000, fPCBlockFlag6000 = 0x6000, fPCBlockFlag8000 = 0x8000 }; +// v3 has fCCisLiveOnExit, fUnrolled, fAlignBlock extern PCodeBlock *pcbasicblocks; extern PCodeBlock *pclastblock; diff --git a/includes/compiler/StackFrame.h b/includes/compiler/StackFrame.h index 16c5316..af81845 100644 --- a/includes/compiler/StackFrame.h +++ b/includes/compiler/StackFrame.h @@ -7,12 +7,12 @@ #pragma options align=mac68k #endif -enum ObjClass { +typedef enum ObjClass { ObjClass0, ObjClass1, ObjClass2, ObjClassMax -}; +} ObjClass; extern Boolean requires_frame; extern Boolean makes_call; diff --git a/includes/compiler/Switch.h b/includes/compiler/Switch.h index 15e7d51..aeac03e 100644 --- a/includes/compiler/Switch.h +++ b/includes/compiler/Switch.h @@ -18,7 +18,7 @@ typedef struct CaseRange { struct SwitchInfo { SwitchCase *cases; CLabel *defaultlabel; - void *x8; + Type *x8; }; extern ObjectList *switchtables; diff --git a/includes/compiler/TOC.h b/includes/compiler/TOC.h index c5eabb0..2d6d3be 100644 --- a/includes/compiler/TOC.h +++ b/includes/compiler/TOC.h @@ -13,13 +13,20 @@ typedef struct CodeLabelList { CLabel *label; } CodeLabelList; +typedef struct PoolEntry { + struct PoolEntry *next; + Object *object; + SInt32 offset; + void *buffer; +} PoolEntry; + extern ObjectList *toclist; extern ObjectList *exceptionlist; extern void *descriptorlist; -extern void *floatconstpool; -extern void *doubleconstpool; +extern PoolEntry *floatconstpool; +extern PoolEntry *doubleconstpool; extern ObjectList *floatconstlist; -extern void *vectorconstpool; +extern PoolEntry *vectorconstpool; extern ObjectList *vectorconstlist; extern Object toc0; extern Boolean no_descriptors; @@ -34,8 +41,8 @@ extern void referenceIndirectPointer(Object *obj); extern Object *createIndirect(Object *obj, Boolean flag1, Boolean flag2); extern Object *createfloatconstant(Type *type, Float *data); extern Object *createvectorconstant(Type *type, MWVector128 *data); -extern void DeclarePooledConstants(); -extern Object *CreateFloatConst(Type *type, Float *data, SInt32 *unkptr); +extern void DeclarePooledConstants(void); +extern Object *CreateFloatConst(Type *type, Float *data, SInt32 *pOffset); extern void dumpcodelabels(Object *func); typedef struct COVCResult { // this struct might be used in other places too??? diff --git a/includes/compiler/common.h b/includes/compiler/common.h index b5cb718..5eefd2c 100644 --- a/includes/compiler/common.h +++ b/includes/compiler/common.h @@ -235,6 +235,7 @@ typedef enum TemplDepSubType { enum { Q_CONST = 1, Q_VOLATILE = 2, + Q_CV = Q_CONST | Q_VOLATILE, Q_ASM = 4, Q_PASCAL = 8, Q_INLINE = 0x10, diff --git a/includes/compiler/enode.h b/includes/compiler/enode.h index 3697135..f7174f0 100644 --- a/includes/compiler/enode.h +++ b/includes/compiler/enode.h @@ -230,6 +230,7 @@ enum { #define ENODE_IS2(_enode, _etype1, _etype2) ( ENODE_IS((_enode), (_etype1)) || ENODE_IS((_enode), (_etype2)) ) #define ENODE_IS3(_enode, _etype1, _etype2, _etype3) ( ENODE_IS((_enode), (_etype1)) || ENODE_IS((_enode), (_etype2)) || ENODE_IS((_enode), (_etype3)) ) #define ENODE_IS4(_enode, _etype1, _etype2, _etype3, _etype4) ( ENODE_IS((_enode), (_etype1)) || ENODE_IS((_enode), (_etype2)) || ENODE_IS((_enode), (_etype3)) || ENODE_IS((_enode), (_etype4)) ) +#define ENODE_IS5(_enode, _etype1, _etype2, _etype3, _etype4, _etype5) ( ENODE_IS((_enode), (_etype1)) || ENODE_IS((_enode), (_etype2)) || ENODE_IS((_enode), (_etype3)) || ENODE_IS((_enode), (_etype4)) || ENODE_IS((_enode), (_etype5)) ) #define ENODE_IS_RANGE(_enode, _lo, _hi) ( ((_enode)->type >= (_lo)) && ((_enode)->type <= (_hi)) ) #define ENODE_QUALS(_enode) ( (UInt32) ( (_enode)->flags & ENODE_FLAG_QUALS ) ) #define ENODE_IS_INDIRECT_TO(_enode, _etype) ( ENODE_IS((_enode), EINDIRECT) && ENODE_IS((_enode)->data.monadic, (_etype)) ) @@ -288,6 +289,7 @@ enum { case EBCLR: \ case EBSET +// 9 to 0x2F #define ENODE_CASE_DIADIC_ALL \ case EMUL: \ case EMULV: \ diff --git a/includes/compiler/objects.h b/includes/compiler/objects.h index a9816cf..52bbf36 100644 --- a/includes/compiler/objects.h +++ b/includes/compiler/objects.h @@ -156,12 +156,12 @@ struct Object { TemplFuncInstance *inst; PTFList *ptfList; ObjectList *argList; - } func; + } func; // Used with DFUNC and DVFUNC struct { char *data; SInt32 size; InlineXRef *xrefs; - } ifunc; + } ifunc; // Used with DINLINEFUNC struct { VarInfo *info; SInt32 uid; @@ -198,14 +198,6 @@ enum { OBJECT_FLAGS_60 = 0x60 // lib export }; -enum { - OBJECT_SCLASS_101 = 0x101, - OBJECT_SCLASS_102 = 0x102, - OBJECT_SCLASS_103 = 0x103, - OBJECT_SCLASS_104 = 0x104, - OBJECT_SCLASS_12B = 0x12B -}; - #define OBJ_BASE(obj) ((ObjBase *) (obj)) #define OBJ_ENUM_CONST(obj) ((ObjEnumConst *) (obj)) #define OBJ_TYPE(obj) ((ObjType *) (obj)) @@ -238,6 +230,8 @@ enum { VarInfoFlag80 = 0x80 }; +#define OBJECT_OR_ALIAS(_object) ( ((_object)->datatype == DALIAS) ? ((_object)->u.alias.object) : (_object) ) + // placing these here until further notice // unknown name, mwcppc.exe 7.0: 484870 diff --git a/includes/compiler/types.h b/includes/compiler/types.h index 3bbba4f..4d6e16e 100644 --- a/includes/compiler/types.h +++ b/includes/compiler/types.h @@ -142,8 +142,8 @@ struct ClassList { // checked via CPrec struct VClassList { // checked via CPrec VClassList *next; TypeClass *base; - SInt32 offset; - SInt32 voffset; + SInt32 offset; // offset within the class instance + SInt32 voffset; // offset within the vtable Boolean has_override; char alignsave; }; @@ -205,7 +205,7 @@ enum { CLASS_FLAGS_100 = 0x100, // is TemplClass CLASS_FLAGS_800 = 0x800, // is TemplClassInst CLASS_FLAGS_900 = 0x900, - CLASS_FLAGS_1000 = 0x1000, + CLASS_FLAGS_1000 = 0x1000, // is empty class CLASS_FLAGS_2000 = 0x2000, CLASS_FLAGS_4000 = 0x4000, CLASS_FLAGS_8000 = 0x8000 @@ -215,7 +215,8 @@ enum { enum { CLASS_EFLAGS_INTERNAL = 1, CLASS_EFLAGS_IMPORT = 2, - CLASS_EFLAGS_EXPORT = 4 + CLASS_EFLAGS_EXPORT = 4, + CLASS_EFLAGS_F0 = 0xF0 }; enum { @@ -269,8 +270,10 @@ enum { FUNC_FLAGS_4000 = 0x4000, // objc method? FUNC_FLAGS_CONST = 0x8000, FUNC_FLAGS_VOLATILE = 0x10000, + FUNC_FLAGS_CV = FUNC_FLAGS_CONST | FUNC_FLAGS_VOLATILE, FUNC_FLAGS_100000 = 0x100000, // is template? FUNC_FLAGS_200000 = 0x200000, + FUNC_FLAGS_400000 = 0x400000, // covariant? FUNC_FLAGS_800000 = 0x800000, FUNC_FLAGS_900000 = 0x900000, FUNC_FLAGS_4000000 = 0x4000000, @@ -412,10 +415,12 @@ struct TypeList { #define IS_TYPE_INT_OR_FLOAT(ty) ( IS_TYPE_INT(ty) || IS_TYPE_FLOAT(ty) ) #define IS_TYPE_STRUCT(ty) ( (ty)->type == TYPESTRUCT ) #define IS_TYPE_CLASS(ty) ( (ty)->type == TYPECLASS ) +#define IS_TYPE_SOM_CLASS(ty) ( (ty)->type == TYPECLASS && TYPE_CLASS((ty))->sominfo ) #define IS_TYPE_OBJC_CLASS(ty) ( (ty)->type == TYPECLASS && TYPE_CLASS((ty))->objcinfo ) #define IS_TYPE_FUNC(ty) ( (ty)->type == TYPEFUNC ) #define IS_TYPEFUNC_METHOD(ty) ( (ty)->flags & FUNC_FLAGS_METHOD ) #define IS_TYPE_METHOD(ty) ( IS_TYPE_FUNC(ty) && IS_TYPEFUNC_METHOD(TYPE_FUNC(ty)) ) +#define IS_TYPE_NONMETHOD(ty) ( IS_TYPE_FUNC(ty) && !IS_TYPEFUNC_METHOD(TYPE_FUNC(ty)) ) #define IS_TYPE_NONSTATIC_METHOD(ty) ( IS_TYPE_FUNC(ty) && IS_TYPEFUNC_METHOD(TYPE_FUNC(ty)) && !TYPE_METHOD(ty)->x26 ) #define IS_TYPE_STATIC_METHOD(ty) ( IS_TYPE_FUNC(ty) && IS_TYPEFUNC_METHOD(TYPE_FUNC(ty)) && TYPE_METHOD(ty)->x26 ) #define IS_TYPEFUNC_NONSTATIC_METHOD(ty) ( IS_TYPEFUNC_METHOD(ty) && !TYPE_METHOD(ty)->x26 ) @@ -428,7 +433,7 @@ struct TypeList { #define IS_TYPE_ARRAY(ty) ( (ty)->type == TYPEARRAY ) #define IS_TYPE_BITFIELD(ty) ( (ty)->type == TYPEBITFIELD ) #define IS_TYPE_TEMPLDEPEXPR(ty) ( (ty)->type == TYPETEMPLDEPEXPR ) -#define IS_TYPESTRUCT_VECTOR(ty) ( TYPE_STRUCT(ty)->stype >= STRUCT_TYPE_4 && TYPE_STRUCT(ty)->stype <= STRUCT_TYPE_E ) +#define IS_TYPESTRUCT_VECTOR(ty) ( (ty)->stype >= STRUCT_TYPE_4 && (ty)->stype <= STRUCT_TYPE_E ) #define IS_TYPE_VECTOR(ty) ( (ty)->type == TYPESTRUCT && IS_TYPESTRUCT_VECTOR(TYPE_STRUCT(ty)) ) #define IS_TYPE_NONVECTOR_STRUCT(ty) ( (ty)->type == TYPESTRUCT && !IS_TYPESTRUCT_VECTOR(TYPE_STRUCT(ty)) ) #define IS_TYPE_MEMBERPOINTER(ty) ( (ty)->type == TYPEMEMBERPOINTER ) diff --git a/includes/cos.h b/includes/cos.h index 3cb9402..f49ed63 100644 --- a/includes/cos.h +++ b/includes/cos.h @@ -22,7 +22,7 @@ extern SInt32 COS_GetTicks(); extern SInt32 COS_GetTime(); extern void COS_GetString(char *buffer, SInt16 strListID, SInt16 index); extern void COS_GetPString(StringPtr buffer, SInt16 strListID, SInt16 index); -extern Boolean COS_IsMultiByte(const char *str1, const char *str2); +extern Boolean COS_IsMultiByte(const void *str1, const void *str2); extern OSErr COS_FileNew(const FSSpec *spec, SInt16 *refNum, OSType creator, OSType fileType); extern OSErr COS_FileOpen(const FSSpec *spec, SInt16 *refNum); extern OSErr COS_FileGetType(const FSSpec *spec, OSType *fileType); @@ -1,5 +1,15 @@ ~/bin/mwccppc -c -g -opt l=4,noschedule,speed -enum min -Iincludes -Isdk_hdrs -w all,nounused -wchar_t on -bool off -Cpp_exceptions off +TODO: +- rename LiveInfo to LiveVariables +- locate COS stuff based off EPPC 8 debug info + - command_line/C++_Parser/Src/Library/OptimizerHelpers.c + - compiler_and_linker/CmdLine_Tools/Embedded_PPC/Tools_EPPC/Src/Options/Glue/TargetOptimizerHelpers-eppc.c + - compiler_and_linker/FrontEnd/Common/COSToolsMemory.h + - compiler_and_linker/FrontEnd/Common/COSToolsFileSpecs.h + - compiler_and_linker/FrontEnd/Common/COSToolsWin32.c +also worth checking ~/s/mwcc/reversing/ftp_backup/Metrowerks/CWPPC6/ext_65/Disk1/PPC_EABI_Tools-CLT/mwcceppc.exe strings + * - has issues [CL / command_line] @@ -58,52 +68,52 @@ DONE compiler_and_linker/CmdLine_Tools/MacOS_PPC/Tools_PPC/Src/Plugin/libimp-ma ---- WarningHelpers.c DONE CCompiler.c -STUB CParser.c +99% CParser.c DONE compiler_and_linker/FrontEnd/Common/CompilerTools.c (except for endian work) ----- CodeGenOptPPC.c ----- IrOptimizer.c -PART CodeGen.c +DONE CodeGenOptPPC.c +99% IrOptimizer.c +90% CodeGen.c MOST CPrep.c MOST CScope.c MOST CMachine.c -STUB CExpr.c -STUB CFunc.c +DONE CExpr.c +90% CFunc.c 99% CTemplateNew.c -STUB CError.c +DONE CError.c 95% ObjGenMachO.c -STUB CDecl.c +85% CDecl.c DONE CMangler.c 99% CSOM.c -STUB CABI.c -STUB CInit.c -STUB CClass.c +95% CABI.c +97% CInit.c +95% CClass.c DONE CIRTransform.c 99% CObjC.c 97% CInline.c -PART CPrepTokenizer.c +99% CPrepTokenizer.c DONE CTemplateTools.c -MOST IroPointerAnalysis.c +80% IroPointerAnalysis.c PART InstrSelection.c -PART IroFlowgraph.c +99% IroFlowgraph.c DONE IroLinearForm.c -MOST IroUtil.c -MOST IroCSE.c +99% IroUtil.c +90% IroCSE.c DONE IroPropagate.c -MOST IROUseDef.c -MOST InlineAsmPPC.c +95% IROUseDef.c +99% InlineAsmPPC.c 99% IroDump.c ----- IroTransform.c -MOST IroVars.c ----- IroEval.c +DONE IroTransform.c +95% IroVars.c +DONE IroEval.c DONE IroJump.c 99% IroRangePropagation.c DONE IroEmptyLoop.c ----- IroUnrollLoop.c +DONE IroUnrollLoop.c 99% IroLoop.c 90% IroExprRegeneration.c DONE IroSubable.c -MOST RegisterInfo.c -MOST TOC.c +DONE RegisterInfo.c +90% TOC.c MOST StackFrame.c DONE Registers.c DONE PCode.c @@ -122,16 +132,16 @@ DONE Coloring.c 90% PCodeAssembly.c 99% Intrinsics.c DONE PPCError.c -STUB CExpr2.c +95% CExpr2.c DONE* CInt64.c -PART CPrec.c +90% CPrec.c 99% CBrowse.c DONE CPreprocess.c 95%? FuncLevelAsmPPC.c 99% CException.c 99% CTemplateClass.c 95% ScanFloat.c ----- CExprConvMatch.c +95% CExprConvMatch.c 98% CRTTI.c DONE CObjCModern.c DONE InlineAsm.c @@ -169,7 +179,7 @@ DONE ?? computelivevariables, dead ---- MachineSimulation821.c 99% InterferenceGraph.c 99% SpillCode.c ----- GCCInlineAsm.c +DONE GCCInlineAsm.c DONE BitVectors.c [Parser] @@ -189,9 +199,13 @@ DONE* (debug) Utils.c DONE# (debug) Parameter.c DONE# (debug) Help.c DONE uContext1.cpp + -- command_line\PluginLib\Src\Library\CWPluginsPrivate.cpp DONE uContextCL.cpp + -- command_line\PluginLib\Src\Library\DropInCompilerLinkerPrivate.cpp DONE uContextSecret.cpp + -- command_line\PluginLib\Src\Internal\CWSecretPluginCallbacks.cpp DONE* ?? COS DONE uContextParser.cpp + -- command_line\PluginLib\Src\Library\CWParserPluginsPrivate.cpp DONE uLibImporter.c ---- Various MSL objects diff --git a/unsorted/uCOS.c b/unsorted/uCOS.c index 68f8832..2a7f643 100644 --- a/unsorted/uCOS.c +++ b/unsorted/uCOS.c @@ -140,7 +140,7 @@ void COS_GetPString(StringPtr buffer, SInt16 strListID, SInt16 index) { GetIndString((StringPtr) buffer, strListID, index); } -Boolean COS_IsMultiByte(const char *str1, const char *str2) { +Boolean COS_IsMultiByte(const void *str1, const void *str2) { return OS_IsMultiByte(str1, str2); } |