summaryrefslogtreecommitdiff
path: root/compiler_and_linker
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2023-01-10 11:05:21 +0000
committerAsh Wolf <ninji@wuffs.org>2023-01-10 11:05:21 +0000
commitaec1b8dddc68ecb8288ec6132932e4c7b4bca09f (patch)
tree8138328fe43bcc5fff690dc60caac79aa570ab2b /compiler_and_linker
parentfcfbafff31869ed808bff0639532db1828660e92 (diff)
downloadMWCC-aec1b8dddc68ecb8288ec6132932e4c7b4bca09f.tar.gz
MWCC-aec1b8dddc68ecb8288ec6132932e4c7b4bca09f.zip
getting close to done
Diffstat (limited to '')
-rw-r--r--compiler_and_linker/FrontEnd/C/CPrep.c2
-rw-r--r--compiler_and_linker/FrontEnd/C/CPrepTokenizer.c1073
-rw-r--r--compiler_and_linker/FrontEnd/C/CScope.c4
-rw-r--r--compiler_and_linker/unsorted/CABI.c2049
-rw-r--r--compiler_and_linker/unsorted/CClass.c2295
-rw-r--r--compiler_and_linker/unsorted/CDecl.c325
-rw-r--r--compiler_and_linker/unsorted/CError.c107
-rw-r--r--compiler_and_linker/unsorted/CException.c33
-rw-r--r--compiler_and_linker/unsorted/CExpr.c286
-rw-r--r--compiler_and_linker/unsorted/CExpr2.c185
-rw-r--r--compiler_and_linker/unsorted/CExprConvMatch.c2517
-rw-r--r--compiler_and_linker/unsorted/CFunc.c3263
-rw-r--r--compiler_and_linker/unsorted/CInit.c30
-rw-r--r--compiler_and_linker/unsorted/CMangler.c117
-rw-r--r--compiler_and_linker/unsorted/CParser.c130
-rw-r--r--compiler_and_linker/unsorted/CPrec.c1750
-rw-r--r--compiler_and_linker/unsorted/CodeGen.c135
-rw-r--r--compiler_and_linker/unsorted/CodeGenOptPPC.c107
-rw-r--r--compiler_and_linker/unsorted/Exceptions.c4
-rw-r--r--compiler_and_linker/unsorted/FuncLevelAsmPPC.c2
-rw-r--r--compiler_and_linker/unsorted/GCCInlineAsm.c215
-rw-r--r--compiler_and_linker/unsorted/InlineAsm.c2
-rw-r--r--compiler_and_linker/unsorted/InlineAsmPPC.c65
-rw-r--r--compiler_and_linker/unsorted/InstrSelection.c227
-rw-r--r--compiler_and_linker/unsorted/IrOptimizer.c381
-rw-r--r--compiler_and_linker/unsorted/IroCSE.c17
-rw-r--r--compiler_and_linker/unsorted/IroEval.c914
-rw-r--r--compiler_and_linker/unsorted/IroFlowgraph.c106
-rw-r--r--compiler_and_linker/unsorted/IroLoop.c10
-rw-r--r--compiler_and_linker/unsorted/IroPointerAnalysis.c1128
-rw-r--r--compiler_and_linker/unsorted/IroPointerAnalysisADTs.c934
-rw-r--r--compiler_and_linker/unsorted/IroTransform.c2793
-rw-r--r--compiler_and_linker/unsorted/IroUnrollLoop.c2264
-rw-r--r--compiler_and_linker/unsorted/IroUtil.c37
-rw-r--r--compiler_and_linker/unsorted/IroVars.c2
-rw-r--r--compiler_and_linker/unsorted/LoopOptimization.c26
-rw-r--r--compiler_and_linker/unsorted/RegisterInfo.c27
-rw-r--r--compiler_and_linker/unsorted/StackFrame.c6
-rw-r--r--compiler_and_linker/unsorted/TOC.c282
39 files changed, 20876 insertions, 2974 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(&current->type, CPrec_GetTypePatch(path->type));
+ if (!path->next)
+ break;
+
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->type, CPrec_GetTypePatch(member->type));
+ CPrec_NamePatch(&current->name, member->name);
+
+ if (!member->next)
+ break;
+
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->name, lst->name);
-
- if (lst->dexpr)
- CPrec_NewPointerPatch(&current->dexpr, CPrec_GetExpressionPatch(lst->dexpr));
- if (lst->type)
- CPrec_NewPointerPatch(&current->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(&current->name, lst->name);
+
+ if (lst->dexpr)
+ CPrec_NewPointerPatch(&current->dexpr, CPrec_GetExpressionPatch(lst->dexpr));
+ if (lst->type)
+ CPrec_NewPointerPatch(&current->type, CPrec_GetTypePatch(lst->type));
+ else
+ CError_FATAL(1167);
+
+ if (!lst->next)
+ break;
- if (lst->next) {
if ((addrPatch = CPrec_FindAddrPatch(lst->next))) {
CPrec_NewPointerPatch(&current->next, addrPatch->value);
- } else {
- next = CPrec_AppendAlign();
- CPrec_NewPointerPatch(&current->next, next);
- current = next;
- lst = lst->next;
- CPrec_NewAddrPatch(lst, next);
- goto restart;
+ break;
}
+
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->selector, arg->selector);
if (arg->name)
@@ -1087,8 +1343,7 @@ static TemplArg *CPrec_GetTemplateArgPatch(TemplArg *arg) {
CPrec_NewPointerPatch(&current->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(&current->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(&current->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(&current->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(&current->u.expr, CPrec_GetExpressionPatch(stmt->u.expr));
+ break;
+ case ST_IFGOTO:
+ case ST_IFNGOTO:
+ CPrec_NewPointerPatch(&current->u.ifgoto.expr, CPrec_GetExpressionPatch(stmt->u.ifgoto.expr));
+ break;
+ case ST_SWITCH:
+ CPrec_NewPointerPatch(&current->u.switchdata, CPrec_GetSwitchInfoPatch(stmt->u.switchdata));
+ break;
+ case ST_ASM:
+ CPrec_NewPointerPatch(&current->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(&current->name, obj->name);
+ CPrec_NewPointerPatch(&current->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(&current->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(&current->name, ivar->name);
+ CPrec_NewPointerPatch(&current->type, CPrec_GetTypePatch(ivar->type));
+
+ if (!ivar->next)
+ break;
+
+ if ((addrPatch = CPrec_FindAddrPatch(ivar->next))) {
+ CPrec_NewPointerPatch(&current->next, addrPatch->value);
+ break;
+ }
+
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->object, CPrec_GetObjectPatch(stub->object));
+ CPrec_NewPointerPatch(&current->tclass, CPrec_GetTypePatch(TYPE(stub->tclass)));
+
+ if (!stub->next)
+ break;
+
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->obj, CPrec_GetObjectPatch(olink->obj));
+
+ if (!olink->next)
+ break;
+
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->object, CPrec_GetObjectPatch(sd->object));
+ if (sd->buffer)
+ CPrec_RawMemPatch(&current->buffer, sd->buffer, sd->object->type->size);
+ if (sd->links)
+ CPrec_NewPointerPatch(&current->links, CPrec_GetOLinkPatch(sd->links));
+
+ if (!sd->next)
+ break;
+
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->obj, CPrec_GetObjectPatch(ca->obj));
+ CPrec_NewPointerPatch(&current->tclass, CPrec_GetTypePatch(TYPE(ca->tclass)));
+
+ if (!ca->next)
+ break;
+
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->object, CPrec_GetObjectPatch(initexpr->object));
+ CPrec_NewPointerPatch(&current->expr, CPrec_GetExpressionPatch(initexpr->expr));
+
+ if (!initexpr->next)
+ break;
+
+ next = CPrec_AppendAlign();
+ CPrec_NewPointerPatch(&current->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(&current->obj, CPrec_GetObjectPatch(act->obj));
+
+ switch (act->actiontype) {
+ case CI_ActionInlineFunc:
+ if (act->u.inlinefunc.stream.firsttoken)
+ CPrec_NewPointerPatch(
+ &current->u.inlinefunc.stream.firsttoken,
+ CPrec_GetTStreamPatch(act->u.inlinefunc.stream.firsttoken, act->u.inlinefunc.stream.tokens));
+ if (act->u.inlinefunc.tclass)
+ CPrec_NewPointerPatch(&current->u.inlinefunc.tclass, CPrec_GetTypePatch(TYPE(act->u.inlinefunc.tclass)));
+ break;
+
+ case CI_ActionMemberFunc:
+ CPrec_NewPointerPatch(&current->u.memberfunc.templ, CPrec_GetTypePatch(TYPE(act->u.memberfunc.templ)));
+ CPrec_NewPointerPatch(&current->u.memberfunc.inst, CPrec_GetTypePatch(TYPE(act->u.memberfunc.inst)));
+ CPrec_NewPointerPatch(&current->u.memberfunc.tmemb, CPrec_GetTemplateMemberPatch(act->u.memberfunc.tmemb));
+ break;
+
+ case CI_ActionTemplateFunc:
+ CPrec_NewPointerPatch(&current->u.templatefunc.func, CPrec_GetTemplateFunctionPatch(act->u.templatefunc.func));
+ CPrec_NewPointerPatch(&current->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(&current->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(&params, 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(&params, 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(&params, 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(&params, 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;