Destructor tracking of temporary variables
This commit is contained in:
parent
56740b630d
commit
6b753c1418
|
@ -1,5 +1,11 @@
|
||||||
rem @echo off
|
rem @echo off
|
||||||
|
|
||||||
|
@call :test constructortest.cpp
|
||||||
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
@call :test copyconstructor.cpp
|
||||||
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
@call :test stdlibtest.c
|
@call :test stdlibtest.c
|
||||||
@if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
int t, n;
|
||||||
|
|
||||||
|
struct C1
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
|
||||||
|
C1(int x);
|
||||||
|
~C1(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
C1::C1(int x) : a(x)
|
||||||
|
{
|
||||||
|
t += a;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
C1::~C1(void)
|
||||||
|
{
|
||||||
|
t -= a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_base(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
C1 x(2);
|
||||||
|
C1 y(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(t == 0 && n == 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_base_loop(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
for(int i=0; i<10; i++)
|
||||||
|
{
|
||||||
|
C1 x(2);
|
||||||
|
C1 y(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(t == 0 && n == 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct C2
|
||||||
|
{
|
||||||
|
C1 c, d;
|
||||||
|
|
||||||
|
C2(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
C2::C2(void)
|
||||||
|
: c(7), d(11)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_member(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
C2 x();
|
||||||
|
C2 y();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(t == 0 && n == 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_member_loop(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
for(int i=0; i<10; i++)
|
||||||
|
{
|
||||||
|
C2 x();
|
||||||
|
C2 y();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(t == 0 && n == 40);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct C3
|
||||||
|
{
|
||||||
|
C2 x, y;
|
||||||
|
};
|
||||||
|
|
||||||
|
void test_default(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
C3 x();
|
||||||
|
C3 y();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(t == 0 && n == 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_default_loop(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
for(int i=0; i<10; i++)
|
||||||
|
{
|
||||||
|
C3 x();
|
||||||
|
C3 y();
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(t == 0 && n == 80);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void test_inline_x(void)
|
||||||
|
{
|
||||||
|
C1 x(1), y(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_inline(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
test_inline_x();
|
||||||
|
|
||||||
|
assert(t == 0 && n == 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void test_inline_xr(void)
|
||||||
|
{
|
||||||
|
C1 x(1), y(2);
|
||||||
|
|
||||||
|
{
|
||||||
|
C1 x(3);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_inline_return(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
test_inline_xr();
|
||||||
|
|
||||||
|
assert(t == 0 && n == 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
test_base();
|
||||||
|
test_base_loop();
|
||||||
|
|
||||||
|
test_member();
|
||||||
|
test_member_loop();
|
||||||
|
|
||||||
|
test_default();
|
||||||
|
test_default_loop();
|
||||||
|
|
||||||
|
test_inline();
|
||||||
|
test_inline_return();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,216 @@
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
int t, n;
|
||||||
|
|
||||||
|
struct C0
|
||||||
|
{
|
||||||
|
int u;
|
||||||
|
|
||||||
|
C0(int a);
|
||||||
|
~C0(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
C0::C0(int a) : u(a)
|
||||||
|
{
|
||||||
|
t += u;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
C0::~C0(void)
|
||||||
|
{
|
||||||
|
t -= u;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct C1
|
||||||
|
{
|
||||||
|
int u;
|
||||||
|
|
||||||
|
C1(int a);
|
||||||
|
~C1(void);
|
||||||
|
C1(const C1 & c);
|
||||||
|
};
|
||||||
|
|
||||||
|
C1::C1(int a) : u(a)
|
||||||
|
{
|
||||||
|
t += u;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
C1::~C1(void)
|
||||||
|
{
|
||||||
|
t -= u;
|
||||||
|
}
|
||||||
|
|
||||||
|
C1::C1(const C1 & c) : u(c.u)
|
||||||
|
{
|
||||||
|
t += u;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_dcopy_init(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
C0 x(4);
|
||||||
|
C0 y(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(n == 1 && t == -4);
|
||||||
|
|
||||||
|
t = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_copy_init(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
C1 x(4);
|
||||||
|
C1 y(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(n == 2 && t == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct C2
|
||||||
|
{
|
||||||
|
C1 a, b;
|
||||||
|
|
||||||
|
C2(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
C2::C2(void) : a(1), b(3)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void test_minit(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
C2 x;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(n == 2 && t == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_minit_copy(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
C2 x;
|
||||||
|
C2 y(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(n == 4 && t == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int k;
|
||||||
|
|
||||||
|
inline void test_param_fv(C2 c)
|
||||||
|
{
|
||||||
|
k += c.a.u;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_param_fr(C2 & c)
|
||||||
|
{
|
||||||
|
k += c.a.u;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_param_value(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
C2 x;
|
||||||
|
test_param_fv(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(n == 4 && t == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_param_ref(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
C2 x;
|
||||||
|
test_param_fr(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(n == 2 && t == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
C2 test_ret_v(void)
|
||||||
|
{
|
||||||
|
C2 c;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
C2 & test_ret_r(C2 & r)
|
||||||
|
{
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_return_value(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
C2 c(test_ret_v());
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(n == 4 && t == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_return_reference(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
C2 d;
|
||||||
|
C2 c(test_ret_r(d));
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(n == 2 && t == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_retparam_value(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
test_param_fv(test_ret_v());
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(n == 4 && t == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_retparam_reference(void)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
test_param_fr(test_ret_v());
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(n == 4 && t == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
test_dcopy_init();
|
||||||
|
test_copy_init();
|
||||||
|
test_minit();
|
||||||
|
test_minit_copy();
|
||||||
|
test_param_value();
|
||||||
|
test_param_ref();
|
||||||
|
test_return_value();
|
||||||
|
#endif
|
||||||
|
test_retparam_value();
|
||||||
|
// test_retparam_reference();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -123,7 +123,7 @@ void DeclarationScope::End(const Location& loc)
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression::Expression(const Location& loc, ExpressionType type)
|
Expression::Expression(const Location& loc, ExpressionType type)
|
||||||
: mLocation(loc), mEndLocation(loc), mType(type), mLeft(nullptr), mRight(nullptr), mConst(false)
|
: mLocation(loc), mEndLocation(loc), mType(type), mLeft(nullptr), mRight(nullptr), mConst(false), mDecType(nullptr), mDecValue(nullptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -133,6 +133,148 @@ Expression::~Expression(void)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Expression::Dump(int ident) const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ident; i++)
|
||||||
|
printf("| ");
|
||||||
|
|
||||||
|
switch (mType)
|
||||||
|
{
|
||||||
|
case EX_ERROR:
|
||||||
|
printf("ERROR");
|
||||||
|
break;
|
||||||
|
case EX_VOID:
|
||||||
|
printf("VOID");
|
||||||
|
break;
|
||||||
|
case EX_CONSTANT:
|
||||||
|
printf("CONST");
|
||||||
|
break;
|
||||||
|
case EX_VARIABLE:
|
||||||
|
printf("VAR");
|
||||||
|
break;
|
||||||
|
case EX_ASSIGNMENT:
|
||||||
|
printf("ASSIGN<%s>", TokenNames[mToken]);
|
||||||
|
break;
|
||||||
|
case EX_INITIALIZATION:
|
||||||
|
printf("INIT");
|
||||||
|
break;
|
||||||
|
case EX_BINARY:
|
||||||
|
printf("BINARY<%s>", TokenNames[mToken]);
|
||||||
|
break;
|
||||||
|
case EX_RELATIONAL:
|
||||||
|
printf("RELATIONAL<%s>", TokenNames[mToken]);
|
||||||
|
break;
|
||||||
|
case EX_PREINCDEC:
|
||||||
|
printf("PREOP<%s>", TokenNames[mToken]);
|
||||||
|
break;
|
||||||
|
case EX_PREFIX:
|
||||||
|
printf("PREFIX<%s>", TokenNames[mToken]);
|
||||||
|
break;
|
||||||
|
case EX_POSTFIX:
|
||||||
|
printf("POSTFIX<%s>", TokenNames[mToken]);
|
||||||
|
break;
|
||||||
|
case EX_POSTINCDEC:
|
||||||
|
printf("POSTOP<%s>", TokenNames[mToken]);
|
||||||
|
break;
|
||||||
|
case EX_INDEX:
|
||||||
|
printf("INDEX");
|
||||||
|
break;
|
||||||
|
case EX_QUALIFY:
|
||||||
|
printf("QUALIFY");
|
||||||
|
break;
|
||||||
|
case EX_CALL:
|
||||||
|
printf("CALL");
|
||||||
|
break;
|
||||||
|
case EX_INLINE:
|
||||||
|
printf("INLINE");
|
||||||
|
break;
|
||||||
|
case EX_LIST:
|
||||||
|
printf("LIST");
|
||||||
|
break;
|
||||||
|
case EX_RETURN:
|
||||||
|
printf("RETURN");
|
||||||
|
break;
|
||||||
|
case EX_SEQUENCE:
|
||||||
|
printf("SEQUENCE");
|
||||||
|
break;
|
||||||
|
case EX_WHILE:
|
||||||
|
printf("WHILE");
|
||||||
|
break;
|
||||||
|
case EX_IF:
|
||||||
|
printf("IF");
|
||||||
|
break;
|
||||||
|
case EX_ELSE:
|
||||||
|
printf("ELSE");
|
||||||
|
break;
|
||||||
|
case EX_FOR:
|
||||||
|
printf("FOR");
|
||||||
|
break;
|
||||||
|
case EX_DO:
|
||||||
|
printf("DO");
|
||||||
|
break;
|
||||||
|
case EX_SCOPE:
|
||||||
|
printf("SCOPE");
|
||||||
|
break;
|
||||||
|
case EX_BREAK:
|
||||||
|
printf("BREAK");
|
||||||
|
break;
|
||||||
|
case EX_CONTINUE:
|
||||||
|
printf("CONTINUE");
|
||||||
|
break;
|
||||||
|
case EX_TYPE:
|
||||||
|
printf("TYPE");
|
||||||
|
break;
|
||||||
|
case EX_TYPECAST:
|
||||||
|
printf("TYPECAST");
|
||||||
|
break;
|
||||||
|
case EX_LOGICAL_AND:
|
||||||
|
printf("AND");
|
||||||
|
break;
|
||||||
|
case EX_LOGICAL_OR:
|
||||||
|
printf("OR");
|
||||||
|
break;
|
||||||
|
case EX_LOGICAL_NOT:
|
||||||
|
printf("NOT");
|
||||||
|
break;
|
||||||
|
case EX_ASSEMBLER:
|
||||||
|
printf("ASSEMBLER");
|
||||||
|
break;
|
||||||
|
case EX_UNDEFINED:
|
||||||
|
printf("UNDEFINED");
|
||||||
|
break;
|
||||||
|
case EX_SWITCH:
|
||||||
|
printf("SWITCH");
|
||||||
|
break;
|
||||||
|
case EX_CASE:
|
||||||
|
printf("CASE");
|
||||||
|
break;
|
||||||
|
case EX_DEFAULT:
|
||||||
|
printf("DEFAULT");
|
||||||
|
break;
|
||||||
|
case EX_CONDITIONAL:
|
||||||
|
printf("COND");
|
||||||
|
break;
|
||||||
|
case EX_ASSUME:
|
||||||
|
printf("ASSUME");
|
||||||
|
break;
|
||||||
|
case EX_BANKOF:
|
||||||
|
printf("BANKOF");
|
||||||
|
break;
|
||||||
|
case EX_CONSTRUCT:
|
||||||
|
printf("CONSTRUCT");
|
||||||
|
break;
|
||||||
|
case EX_CLEANUP:
|
||||||
|
printf("CLEANUP");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
if (mLeft)
|
||||||
|
mLeft->Dump(ident + 1);
|
||||||
|
if (mRight)
|
||||||
|
mRight->Dump(ident + 1);
|
||||||
|
}
|
||||||
|
|
||||||
bool Expression::HasSideEffects(void) const
|
bool Expression::HasSideEffects(void) const
|
||||||
{
|
{
|
||||||
switch (mType)
|
switch (mType)
|
||||||
|
@ -635,8 +777,8 @@ Expression* Expression::ConstantFold(Errors * errors)
|
||||||
Declaration::Declaration(const Location& loc, DecType type)
|
Declaration::Declaration(const Location& loc, DecType type)
|
||||||
: mLocation(loc), mEndLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mQualIdent(nullptr),
|
: mLocation(loc), mEndLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mQualIdent(nullptr),
|
||||||
mSize(0), mOffset(0), mFlags(0), mComplexity(0), mLocalSize(0),
|
mSize(0), mOffset(0), mFlags(0), mComplexity(0), mLocalSize(0),
|
||||||
mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mConst(nullptr),
|
mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mPrev(nullptr), mConst(nullptr),
|
||||||
mConstructor(nullptr), mDestructor(nullptr),
|
mConstructor(nullptr), mDestructor(nullptr), mCopyConstructor(nullptr),
|
||||||
mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1),
|
mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1),
|
||||||
mInteger(0), mNumber(0), mMinValue(-0x80000000LL), mMaxValue(0x7fffffffLL), mFastCallBase(0), mFastCallSize(0), mStride(0), mStripe(1),
|
mInteger(0), mNumber(0), mMinValue(-0x80000000LL), mMaxValue(0x7fffffffLL), mFastCallBase(0), mFastCallSize(0), mStride(0), mStripe(1),
|
||||||
mCompilerOptions(0), mUseCount(0)
|
mCompilerOptions(0), mUseCount(0)
|
||||||
|
@ -653,6 +795,18 @@ int Declaration::Stride(void) const
|
||||||
return mStride > 0 ? mStride : mBase->mSize;
|
return mStride > 0 ? mStride : mBase->mSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Declaration* Declaration::Last(void)
|
||||||
|
{
|
||||||
|
mPrev = nullptr;
|
||||||
|
Declaration* p = this;
|
||||||
|
while (p->mNext)
|
||||||
|
{
|
||||||
|
p->mNext->mPrev = p;
|
||||||
|
p = p->mNext;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
Declaration* Declaration::Clone(void)
|
Declaration* Declaration::Clone(void)
|
||||||
{
|
{
|
||||||
Declaration* ndec = new Declaration(mLocation, mType);
|
Declaration* ndec = new Declaration(mLocation, mType);
|
||||||
|
@ -945,6 +1099,8 @@ bool Declaration::IsSame(const Declaration* dec) const
|
||||||
return mIdent == dec->mIdent;
|
return mIdent == dec->mIdent;
|
||||||
else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY)
|
else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY)
|
||||||
return this->Stride() == dec->Stride() && mBase->IsSame(dec->mBase);
|
return this->Stride() == dec->Stride() && mBase->IsSame(dec->mBase);
|
||||||
|
else if (mType == DT_TYPE_REFERENCE)
|
||||||
|
return mBase->IsSame(dec->mBase);
|
||||||
else if (mType == DT_TYPE_STRUCT)
|
else if (mType == DT_TYPE_STRUCT)
|
||||||
return mScope == dec->mScope || (mIdent == dec->mIdent && mSize == dec->mSize);
|
return mScope == dec->mScope || (mIdent == dec->mIdent && mSize == dec->mSize);
|
||||||
else if (mType == DT_TYPE_FUNCTION)
|
else if (mType == DT_TYPE_FUNCTION)
|
||||||
|
|
|
@ -185,7 +185,8 @@ enum ExpressionType
|
||||||
EX_CONDITIONAL,
|
EX_CONDITIONAL,
|
||||||
EX_ASSUME,
|
EX_ASSUME,
|
||||||
EX_BANKOF,
|
EX_BANKOF,
|
||||||
EX_CONSTRUCT
|
EX_CONSTRUCT,
|
||||||
|
EX_CLEANUP,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Expression
|
class Expression
|
||||||
|
@ -208,6 +209,8 @@ public:
|
||||||
bool HasSideEffects(void) const;
|
bool HasSideEffects(void) const;
|
||||||
|
|
||||||
bool IsSame(const Expression* exp) const;
|
bool IsSame(const Expression* exp) const;
|
||||||
|
|
||||||
|
void Dump(int ident) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Declaration
|
class Declaration
|
||||||
|
@ -219,7 +222,7 @@ public:
|
||||||
Location mLocation, mEndLocation;
|
Location mLocation, mEndLocation;
|
||||||
DecType mType;
|
DecType mType;
|
||||||
Token mToken;
|
Token mToken;
|
||||||
Declaration* mBase, *mParams, * mNext, * mConst, * mConstructor, * mDestructor;
|
Declaration* mBase, *mParams, * mNext, * mPrev, * mConst, * mConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment;
|
||||||
Expression* mValue;
|
Expression* mValue;
|
||||||
DeclarationScope* mScope;
|
DeclarationScope* mScope;
|
||||||
int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize, mAlignment, mFastCallBase, mFastCallSize, mStride, mStripe;
|
int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize, mAlignment, mFastCallBase, mFastCallSize, mStride, mStripe;
|
||||||
|
@ -249,6 +252,7 @@ public:
|
||||||
Declaration* ToStriped(int stripe);
|
Declaration* ToStriped(int stripe);
|
||||||
Declaration* ToStriped(Errors* errors);
|
Declaration* ToStriped(Errors* errors);
|
||||||
Declaration* Clone(void);
|
Declaration* Clone(void);
|
||||||
|
Declaration* Last(void);
|
||||||
|
|
||||||
int Stride(void) const;
|
int Stride(void) const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,7 +14,7 @@ class Ident;
|
||||||
enum ErrorID
|
enum ErrorID
|
||||||
{
|
{
|
||||||
EINFO_GENERIC = 1000,
|
EINFO_GENERIC = 1000,
|
||||||
|
|
||||||
EWARN_GENERIC = 2000,
|
EWARN_GENERIC = 2000,
|
||||||
EWARN_CONSTANT_TRUNCATED,
|
EWARN_CONSTANT_TRUNCATED,
|
||||||
EWARN_UNKNOWN_PRAGMA,
|
EWARN_UNKNOWN_PRAGMA,
|
||||||
|
@ -78,6 +78,8 @@ enum ErrorID
|
||||||
ERRO_NO_MATCHING_FUNCTION_CALL,
|
ERRO_NO_MATCHING_FUNCTION_CALL,
|
||||||
ERRO_AMBIGUOUS_FUNCTION_CALL,
|
ERRO_AMBIGUOUS_FUNCTION_CALL,
|
||||||
EERR_NO_DEFAULT_CONSTRUCTOR,
|
EERR_NO_DEFAULT_CONSTRUCTOR,
|
||||||
|
EERR_INVALID_OPERATOR,
|
||||||
|
EERR_MISSING_TEMP,
|
||||||
|
|
||||||
ERRR_STACK_OVERFLOW,
|
ERRR_STACK_OVERFLOW,
|
||||||
ERRR_INVALID_NUMBER,
|
ERRR_INVALID_NUMBER,
|
||||||
|
|
|
@ -429,6 +429,14 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec)
|
||||||
|
|
||||||
mFunctions.Push(dec);
|
mFunctions.Push(dec);
|
||||||
|
|
||||||
|
Declaration* pdec = dec->mBase->mParams;
|
||||||
|
while (pdec)
|
||||||
|
{
|
||||||
|
if (pdec->mBase->mType == DT_TYPE_STRUCT && (pdec->mBase->mCopyConstructor || pdec->mBase->mDestructor))
|
||||||
|
dec->mBase->mFlags |= DTF_STACKCALL;
|
||||||
|
pdec = pdec->mNext;
|
||||||
|
}
|
||||||
|
|
||||||
dec->mFlags |= DTF_ANALYZED;
|
dec->mFlags |= DTF_ANALYZED;
|
||||||
dec->mFlags |= DTF_FUNC_INTRSAVE;
|
dec->mFlags |= DTF_FUNC_INTRSAVE;
|
||||||
|
|
||||||
|
@ -679,7 +687,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
||||||
|
|
||||||
if (pdec && !(ldec->mBase->mFlags & DTF_VARIADIC) && !(ldec->mFlags & (DTF_INTRINSIC | DTF_FUNC_ASSEMBLER)))
|
if (pdec && !(ldec->mBase->mFlags & DTF_VARIADIC) && !(ldec->mFlags & (DTF_INTRINSIC | DTF_FUNC_ASSEMBLER)))
|
||||||
{
|
{
|
||||||
#if 1
|
#if 0
|
||||||
if (mCompilerOptions & COPT_OPTIMIZE_BASIC)
|
if (mCompilerOptions & COPT_OPTIMIZE_BASIC)
|
||||||
{
|
{
|
||||||
if (!(pdec->mFlags & DTF_FPARAM_NOCONST))
|
if (!(pdec->mFlags & DTF_FPARAM_NOCONST))
|
||||||
|
@ -714,8 +722,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pdec && pdec->mBase->mType == DT_TYPE_STRUCT && pdec->mBase->mCopyConstructor)
|
||||||
|
{
|
||||||
|
AnalyzeProcedure(pdec->mBase->mCopyConstructor->mValue, pdec->mBase->mCopyConstructor);
|
||||||
|
RegisterCall(procDec, pdec->mBase->mCopyConstructor);
|
||||||
|
}
|
||||||
|
|
||||||
if (pex->mType == EX_CALL && pex->mDecType->mType == DT_TYPE_STRUCT)
|
if (pex->mType == EX_CALL && pex->mDecType->mType == DT_TYPE_STRUCT && !(pdec && pdec->mBase->mType == DT_TYPE_REFERENCE))
|
||||||
ldec->mBase->mFlags |= DTF_STACKCALL;
|
ldec->mBase->mFlags |= DTF_STACKCALL;
|
||||||
|
|
||||||
if (pdec)
|
if (pdec)
|
||||||
|
@ -734,7 +748,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
||||||
return Analyze(exp->mRight, procDec, false);
|
return Analyze(exp->mRight, procDec, false);
|
||||||
case EX_RETURN:
|
case EX_RETURN:
|
||||||
if (exp->mLeft)
|
if (exp->mLeft)
|
||||||
|
{
|
||||||
RegisterProc(Analyze(exp->mLeft, procDec, false));
|
RegisterProc(Analyze(exp->mLeft, procDec, false));
|
||||||
|
if (procDec->mBase->mBase && procDec->mBase->mBase->mType == DT_TYPE_STRUCT && procDec->mBase->mBase->mCopyConstructor)
|
||||||
|
{
|
||||||
|
AnalyzeProcedure(procDec->mBase->mBase->mCopyConstructor->mValue, procDec->mBase->mBase->mCopyConstructor);
|
||||||
|
RegisterCall(procDec, procDec->mBase->mBase->mCopyConstructor);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case EX_SEQUENCE:
|
case EX_SEQUENCE:
|
||||||
do
|
do
|
||||||
|
@ -761,6 +782,10 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
||||||
if (exp->mLeft->mRight)
|
if (exp->mLeft->mRight)
|
||||||
Analyze(exp->mLeft->mRight, procDec, false);
|
Analyze(exp->mLeft->mRight, procDec, false);
|
||||||
return Analyze(exp->mRight, procDec, false);
|
return Analyze(exp->mRight, procDec, false);
|
||||||
|
|
||||||
|
case EX_CLEANUP:
|
||||||
|
Analyze(exp->mRight, procDec, false);
|
||||||
|
return Analyze(exp->mLeft, procDec, lhs);
|
||||||
|
|
||||||
case EX_WHILE:
|
case EX_WHILE:
|
||||||
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
|
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
|
||||||
|
|
|
@ -16017,7 +16017,7 @@ void InterCodeProcedure::Close(void)
|
||||||
{
|
{
|
||||||
GrowingTypeArray tstack(IT_NONE);
|
GrowingTypeArray tstack(IT_NONE);
|
||||||
|
|
||||||
CheckFunc = !strcmp(mIdent->mString, "main");
|
CheckFunc = !strcmp(mIdent->mString, "test_retparam_value");
|
||||||
|
|
||||||
mEntryBlock = mBlocks[0];
|
mEntryBlock = mBlocks[0];
|
||||||
|
|
||||||
|
|
|
@ -856,14 +856,14 @@ void InterCodeGenerator::BuildSwitchTree(InterCodeProcedure* proc, Expression* e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterCodeGenerator::UnwindDestructStack(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, DestructStack* stack, DestructStack* bottom)
|
void InterCodeGenerator::UnwindDestructStack(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, DestructStack* stack, DestructStack* bottom, InlineMapper* inlineMapper)
|
||||||
{
|
{
|
||||||
while (stack && stack != bottom)
|
while (stack && stack != bottom)
|
||||||
{
|
{
|
||||||
if (stack->mDestruct)
|
if (stack->mDestruct)
|
||||||
{
|
{
|
||||||
DestructStack* destack = nullptr;
|
DestructStack* destack = nullptr;
|
||||||
TranslateExpression(procType, proc, block, stack->mDestruct, destack, BranchTarget(), BranchTarget(), nullptr);
|
TranslateExpression(procType, proc, block, stack->mDestruct, destack, BranchTarget(), BranchTarget(), inlineMapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
stack = stack->mNext;
|
stack = stack->mNext;
|
||||||
|
@ -873,7 +873,7 @@ void InterCodeGenerator::UnwindDestructStack(Declaration* procType, InterCodePro
|
||||||
mErrors->Error(proc->mLocation, EWARN_DESTRUCTOR_MISMATCH, "Destructor sequence mismatch");
|
mErrors->Error(proc->mLocation, EWARN_DESTRUCTOR_MISMATCH, "Destructor sequence mismatch");
|
||||||
}
|
}
|
||||||
|
|
||||||
InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, const BranchTarget& breakBlock, const BranchTarget& continueBlock, InlineMapper* inlineMapper, bool inlineConstexpr)
|
InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, const BranchTarget& breakBlock, const BranchTarget& continueBlock, InlineMapper* inlineMapper, bool inlineConstexpr, ExValue* lrexp)
|
||||||
{
|
{
|
||||||
DestructStack* destack = nullptr;
|
DestructStack* destack = nullptr;
|
||||||
|
|
||||||
|
@ -1024,13 +1024,20 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
|
||||||
Declaration* rdec = nullptr;
|
Declaration* rdec = nullptr;
|
||||||
if (ftype->mBase->mType != DT_TYPE_VOID)
|
if (ftype->mBase->mType != DT_TYPE_VOID)
|
||||||
{
|
{
|
||||||
int nindex = proc->mNumLocals++;
|
if (lrexp)
|
||||||
nmapper.mResult = nindex;
|
{
|
||||||
|
nmapper.mResultExp = lrexp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int nindex = proc->mNumLocals++;
|
||||||
|
nmapper.mResult = nindex;
|
||||||
|
|
||||||
rdec = new Declaration(ftype->mLocation, DT_VARIABLE);
|
rdec = new Declaration(ftype->mLocation, DT_VARIABLE);
|
||||||
rdec->mVarIndex = nindex;
|
rdec->mVarIndex = nindex;
|
||||||
rdec->mBase = ftype->mBase;
|
rdec->mBase = ftype->mBase;
|
||||||
rdec->mSize = rdec->mBase->mSize;
|
rdec->mSize = rdec->mBase->mSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vl = TranslateExpression(ftype, proc, block, fexp, destack, BranchTarget(), BranchTarget(), &nmapper);
|
vl = TranslateExpression(ftype, proc, block, fexp, destack, BranchTarget(), BranchTarget(), &nmapper);
|
||||||
|
@ -1041,6 +1048,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
|
||||||
block->Close(nmapper.mReturn, nullptr);
|
block->Close(nmapper.mReturn, nullptr);
|
||||||
block = nmapper.mReturn;
|
block = nmapper.mReturn;
|
||||||
|
|
||||||
|
UnwindDestructStack(ftype, proc, block, destack, nullptr, &nmapper);
|
||||||
|
|
||||||
if (rdec)
|
if (rdec)
|
||||||
{
|
{
|
||||||
InterInstruction* ins = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
InterInstruction* ins = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||||
|
@ -1055,10 +1064,214 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
|
||||||
|
|
||||||
return ExValue(rdec->mBase, ins->mDst.mTemp, 1);
|
return ExValue(rdec->mBase, ins->mDst.mTemp, 1);
|
||||||
}
|
}
|
||||||
|
else if (lrexp)
|
||||||
|
{
|
||||||
|
return *lrexp;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return ExValue(TheVoidTypeDeclaration);
|
return ExValue(TheVoidTypeDeclaration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InterCodeGenerator::CopyStruct(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue vl, ExValue vr, InlineMapper* inlineMapper)
|
||||||
|
{
|
||||||
|
if (vl.mType->mCopyConstructor)
|
||||||
|
{
|
||||||
|
Declaration* ccdec = vl.mType->mCopyConstructor;
|
||||||
|
if (!ccdec->mLinkerObject)
|
||||||
|
this->TranslateProcedure(proc->mModule, ccdec->mValue, ccdec);
|
||||||
|
|
||||||
|
bool canInline = (mCompilerOptions & COPT_OPTIMIZE_INLINE) && !(inlineMapper && inlineMapper->mDepth > 10);
|
||||||
|
bool doInline = false;
|
||||||
|
|
||||||
|
if (canInline)
|
||||||
|
{
|
||||||
|
if (ccdec->mFlags & DTF_INLINE)
|
||||||
|
{
|
||||||
|
if ((ccdec->mFlags & DTF_REQUEST_INLINE) || (mCompilerOptions & COPT_OPTIMIZE_AUTO_INLINE))
|
||||||
|
{
|
||||||
|
if (proc->mNativeProcedure || !(ccdec->mFlags & DTF_NATIVE))
|
||||||
|
doInline = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doInline)
|
||||||
|
{
|
||||||
|
DestructStack* destack = nullptr;
|
||||||
|
|
||||||
|
Expression* fexp = ccdec->mValue;
|
||||||
|
Declaration* ftype = ccdec->mBase;
|
||||||
|
|
||||||
|
InlineMapper nmapper;
|
||||||
|
nmapper.mReturn = new InterCodeBasicBlock(proc);
|
||||||
|
nmapper.mVarIndex = proc->mNumLocals;
|
||||||
|
nmapper.mConstExpr = false;
|
||||||
|
proc->mNumLocals += ccdec->mNumVars;
|
||||||
|
if (inlineMapper)
|
||||||
|
nmapper.mDepth = inlineMapper->mDepth + 1;
|
||||||
|
|
||||||
|
Declaration* pdec = ftype->mParams;
|
||||||
|
int nindex = proc->mNumLocals++;
|
||||||
|
Declaration* vdec = new Declaration(exp->mLocation, DT_VARIABLE);
|
||||||
|
|
||||||
|
InterInstruction* ains = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||||
|
ains->mDst.mType = IT_POINTER;
|
||||||
|
ains->mDst.mTemp = proc->AddTemporary(ains->mDst.mType);
|
||||||
|
ains->mConst.mMemory = IM_LOCAL;
|
||||||
|
ains->mConst.mVarIndex = nindex;
|
||||||
|
|
||||||
|
if (!(pdec->mFlags & DTF_FPARAM_CONST))
|
||||||
|
nmapper.mParams[pdec->mVarIndex] = nindex;
|
||||||
|
|
||||||
|
vdec->mVarIndex = nindex;
|
||||||
|
vdec->mBase = pdec->mBase;
|
||||||
|
ains->mConst.mOperandSize = 2;
|
||||||
|
vdec->mSize = ains->mConst.mOperandSize;
|
||||||
|
vdec->mIdent = pdec->mIdent;
|
||||||
|
vdec->mQualIdent = pdec->mQualIdent;
|
||||||
|
block->Append(ains);
|
||||||
|
|
||||||
|
InterInstruction* wins = new InterInstruction(exp->mLocation, IC_STORE);
|
||||||
|
wins->mSrc[1].mMemory = IM_INDIRECT;
|
||||||
|
wins->mSrc[0].mType = InterTypeOf(vl.mType);;
|
||||||
|
wins->mSrc[0].mTemp = vl.mTemp;
|
||||||
|
wins->mSrc[1].mType = IT_POINTER;
|
||||||
|
wins->mSrc[1].mTemp = ains->mDst.mTemp;
|
||||||
|
wins->mSrc[1].mOperandSize = 2;
|
||||||
|
if (!(pdec->mFlags & DTF_FPARAM_CONST))
|
||||||
|
block->Append(wins);
|
||||||
|
|
||||||
|
pdec = pdec->mNext;
|
||||||
|
|
||||||
|
nindex = proc->mNumLocals++;
|
||||||
|
vdec = new Declaration(exp->mLocation, DT_VARIABLE);
|
||||||
|
|
||||||
|
ains = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||||
|
ains->mDst.mType = IT_POINTER;
|
||||||
|
ains->mDst.mTemp = proc->AddTemporary(ains->mDst.mType);
|
||||||
|
ains->mConst.mMemory = IM_LOCAL;
|
||||||
|
ains->mConst.mVarIndex = nindex;
|
||||||
|
|
||||||
|
if (!(pdec->mFlags & DTF_FPARAM_CONST))
|
||||||
|
nmapper.mParams[pdec->mVarIndex] = nindex;
|
||||||
|
|
||||||
|
vdec->mVarIndex = nindex;
|
||||||
|
vdec->mBase = pdec->mBase;
|
||||||
|
ains->mConst.mOperandSize = 2;
|
||||||
|
vdec->mSize = ains->mConst.mOperandSize;
|
||||||
|
vdec->mIdent = pdec->mIdent;
|
||||||
|
vdec->mQualIdent = pdec->mQualIdent;
|
||||||
|
block->Append(ains);
|
||||||
|
|
||||||
|
wins = new InterInstruction(exp->mLocation, IC_STORE);
|
||||||
|
wins->mSrc[1].mMemory = IM_INDIRECT;
|
||||||
|
wins->mSrc[0].mType = InterTypeOf(vr.mType);;
|
||||||
|
wins->mSrc[0].mTemp = vr.mTemp;
|
||||||
|
wins->mSrc[1].mType = IT_POINTER;
|
||||||
|
wins->mSrc[1].mTemp = ains->mDst.mTemp;
|
||||||
|
wins->mSrc[1].mOperandSize = 2;
|
||||||
|
if (!(pdec->mFlags & DTF_FPARAM_CONST))
|
||||||
|
block->Append(wins);
|
||||||
|
|
||||||
|
TranslateExpression(ftype, proc, block, fexp, destack, BranchTarget(), BranchTarget(), &nmapper);
|
||||||
|
|
||||||
|
InterInstruction* jins = new InterInstruction(exp->mLocation, IC_JUMP);
|
||||||
|
block->Append(jins);
|
||||||
|
|
||||||
|
block->Close(nmapper.mReturn, nullptr);
|
||||||
|
block = nmapper.mReturn;
|
||||||
|
}
|
||||||
|
else if (ccdec->mBase->mFlags & DTF_FASTCALL)
|
||||||
|
{
|
||||||
|
InterInstruction* psins = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||||
|
psins->mDst.mType = IT_POINTER;
|
||||||
|
psins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||||
|
psins->mConst.mVarIndex = 0;
|
||||||
|
psins->mConst.mIntConst = 0;
|
||||||
|
psins->mConst.mOperandSize = 2;
|
||||||
|
if (ccdec->mBase->mFlags & DTF_FASTCALL)
|
||||||
|
{
|
||||||
|
psins->mConst.mMemory = IM_FFRAME;
|
||||||
|
psins->mConst.mVarIndex += ccdec->mBase->mFastCallBase;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
psins->mConst.mMemory = IM_FRAME;
|
||||||
|
block->Append(psins);
|
||||||
|
|
||||||
|
InterInstruction* ssins = new InterInstruction(exp->mLocation, IC_STORE);
|
||||||
|
ssins->mSrc[0].mType = IT_POINTER;
|
||||||
|
ssins->mSrc[0].mTemp = vl.mTemp;
|
||||||
|
ssins->mSrc[0].mMemory = IM_INDIRECT;
|
||||||
|
ssins->mSrc[0].mOperandSize = 2;
|
||||||
|
ssins->mSrc[1] = psins->mDst;
|
||||||
|
block->Append(ssins);
|
||||||
|
|
||||||
|
InterInstruction* plins = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||||
|
plins->mDst.mType = IT_POINTER;
|
||||||
|
plins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||||
|
plins->mConst.mVarIndex = 2;
|
||||||
|
plins->mConst.mIntConst = 0;
|
||||||
|
plins->mConst.mOperandSize = 2;
|
||||||
|
if (ccdec->mBase->mFlags & DTF_FASTCALL)
|
||||||
|
{
|
||||||
|
plins->mConst.mMemory = IM_FFRAME;
|
||||||
|
plins->mConst.mVarIndex += ccdec->mBase->mFastCallBase;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
plins->mConst.mMemory = IM_FRAME;
|
||||||
|
block->Append(plins);
|
||||||
|
|
||||||
|
InterInstruction* slins = new InterInstruction(exp->mLocation, IC_STORE);
|
||||||
|
slins->mSrc[0].mType = IT_POINTER;
|
||||||
|
slins->mSrc[0].mTemp = vr.mTemp;
|
||||||
|
slins->mSrc[0].mMemory = IM_INDIRECT;
|
||||||
|
slins->mSrc[0].mOperandSize = 2;
|
||||||
|
slins->mSrc[1] = plins->mDst;
|
||||||
|
block->Append(slins);
|
||||||
|
|
||||||
|
proc->AddCalledFunction(proc->mModule->mProcedures[ccdec->mVarIndex]);
|
||||||
|
|
||||||
|
InterInstruction* pcins = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||||
|
pcins->mDst.mType = IT_POINTER;
|
||||||
|
pcins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||||
|
pcins->mConst.mType = IT_POINTER;
|
||||||
|
pcins->mConst.mVarIndex = ccdec->mVarIndex;
|
||||||
|
pcins->mConst.mIntConst = 0;
|
||||||
|
pcins->mConst.mOperandSize = 2;
|
||||||
|
pcins->mConst.mMemory = IM_GLOBAL;
|
||||||
|
pcins->mConst.mLinkerObject = ccdec->mLinkerObject;
|
||||||
|
block->Append(pcins);
|
||||||
|
|
||||||
|
InterInstruction* cins = new InterInstruction(exp->mLocation, IC_CALL);
|
||||||
|
if (ccdec->mFlags & DTF_NATIVE)
|
||||||
|
cins->mCode = IC_CALL_NATIVE;
|
||||||
|
else
|
||||||
|
cins->mCode = IC_CALL;
|
||||||
|
cins->mSrc[0] = pcins->mDst;
|
||||||
|
cins->mNumOperands = 1;
|
||||||
|
|
||||||
|
block->Append(cins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InterInstruction* cins = new InterInstruction(exp->mLocation, IC_COPY);
|
||||||
|
cins->mSrc[0].mType = IT_POINTER;
|
||||||
|
cins->mSrc[0].mTemp = vr.mTemp;
|
||||||
|
cins->mSrc[0].mMemory = IM_INDIRECT;
|
||||||
|
cins->mSrc[0].mOperandSize = vr.mType->mSize;
|
||||||
|
cins->mSrc[0].mStride = vr.mType->mStripe;
|
||||||
|
|
||||||
|
cins->mSrc[1].mOperandSize = vl.mType->mSize;
|
||||||
|
cins->mSrc[1].mType = IT_POINTER;
|
||||||
|
cins->mSrc[1].mTemp = vl.mTemp;
|
||||||
|
cins->mSrc[1].mMemory = IM_INDIRECT;
|
||||||
|
|
||||||
|
cins->mConst.mOperandSize = vl.mType->mSize;
|
||||||
|
block->Append(cins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, DestructStack*& destack, const BranchTarget& breakBlock, const BranchTarget& continueBlock, InlineMapper* inlineMapper, ExValue* lrexp)
|
InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, DestructStack*& destack, const BranchTarget& breakBlock, const BranchTarget& continueBlock, InlineMapper* inlineMapper, ExValue* lrexp)
|
||||||
{
|
{
|
||||||
Declaration* dec;
|
Declaration* dec;
|
||||||
|
@ -1079,6 +1292,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
if (!exp)
|
if (!exp)
|
||||||
return ExValue(TheVoidTypeDeclaration);
|
return ExValue(TheVoidTypeDeclaration);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EX_CONSTRUCT:
|
case EX_CONSTRUCT:
|
||||||
{
|
{
|
||||||
if (exp->mLeft->mLeft)
|
if (exp->mLeft->mLeft)
|
||||||
|
@ -1095,6 +1309,14 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
exp = exp->mRight;
|
exp = exp->mRight;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EX_CLEANUP:
|
||||||
|
{
|
||||||
|
vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
|
||||||
|
TranslateExpression(procType, proc, block, exp->mRight, destack, breakBlock, continueBlock, inlineMapper);
|
||||||
|
return vl;
|
||||||
|
}
|
||||||
|
|
||||||
case EX_CONSTANT:
|
case EX_CONSTANT:
|
||||||
dec = exp->mDecValue;
|
dec = exp->mDecValue;
|
||||||
switch (dec->mType)
|
switch (dec->mType)
|
||||||
|
@ -2510,7 +2732,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
if (doInline)
|
if (doInline)
|
||||||
{
|
{
|
||||||
return TranslateInline(procType, proc, block, exp, breakBlock, continueBlock, inlineMapper, inlineConstexpr);
|
return TranslateInline(procType, proc, block, exp, breakBlock, continueBlock, inlineMapper, inlineConstexpr, lrexp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2659,6 +2881,31 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
ExValue vp(pdec ? pdec->mBase : TheSignedIntTypeDeclaration, ains->mDst.mTemp, 1);
|
ExValue vp(pdec ? pdec->mBase : TheSignedIntTypeDeclaration, ains->mDst.mTemp, 1);
|
||||||
|
|
||||||
|
if (pdec && pdec->mBase->mType == DT_TYPE_REFERENCE && texp->mType == EX_CALL)
|
||||||
|
{
|
||||||
|
mErrors->Error(texp->mLocation, EERR_MISSING_TEMP, "Missing temporary variable");
|
||||||
|
#if 0
|
||||||
|
int nindex = proc->mNumLocals++;
|
||||||
|
|
||||||
|
Declaration* vdec = new Declaration(exp->mLocation, DT_VARIABLE);
|
||||||
|
|
||||||
|
vdec->mVarIndex = nindex;
|
||||||
|
vdec->mBase = pdec->mBase->mBase;
|
||||||
|
vdec->mSize = pdec->mBase->mBase->mSize;
|
||||||
|
|
||||||
|
InterInstruction* vins = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||||
|
vins->mDst.mType = IT_POINTER;
|
||||||
|
vins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||||
|
vins->mConst.mMemory = IM_LOCAL;
|
||||||
|
vins->mConst.mVarIndex = nindex;
|
||||||
|
vins->mConst.mOperandSize = vdec->mSize;
|
||||||
|
block->Append(vins);
|
||||||
|
|
||||||
|
vp.mType = pdec->mBase->mBase;
|
||||||
|
vp.mTemp = vins->mDst.mTemp;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
vr = TranslateExpression(procType, proc, block, texp, destack, breakBlock, continueBlock, inlineMapper, &vp);
|
vr = TranslateExpression(procType, proc, block, texp, destack, breakBlock, continueBlock, inlineMapper, &vp);
|
||||||
|
|
||||||
if (!(pdec && pdec->mBase->mType == DT_TYPE_REFERENCE) && (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION))
|
if (!(pdec && pdec->mBase->mType == DT_TYPE_REFERENCE) && (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION))
|
||||||
|
@ -2673,6 +2920,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
if (vp.mTemp != vr.mTemp)
|
if (vp.mTemp != vr.mTemp)
|
||||||
{
|
{
|
||||||
|
CopyStruct(proc, exp, block, vp, vr, inlineMapper);
|
||||||
|
#if 0
|
||||||
InterInstruction* cins = new InterInstruction(texp->mLocation, IC_COPY);
|
InterInstruction* cins = new InterInstruction(texp->mLocation, IC_COPY);
|
||||||
cins->mSrc[0].mType = IT_POINTER;
|
cins->mSrc[0].mType = IT_POINTER;
|
||||||
cins->mSrc[0].mTemp = vr.mTemp;
|
cins->mSrc[0].mTemp = vr.mTemp;
|
||||||
|
@ -2687,6 +2936,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
cins->mConst.mOperandSize = vp.mType->mSize;
|
cins->mConst.mOperandSize = vp.mType->mSize;
|
||||||
block->Append(cins);
|
block->Append(cins);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
atotal += vr.mType->mSize;
|
atotal += vr.mType->mSize;
|
||||||
|
@ -2932,21 +3182,33 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
if (inlineMapper)
|
if (inlineMapper)
|
||||||
{
|
{
|
||||||
InterInstruction* ains = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
if (inlineMapper->mResultExp)
|
||||||
ains->mDst.mType = IT_POINTER;
|
{
|
||||||
ains->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
|
ins->mSrc[1].mType = IT_POINTER;
|
||||||
ains->mConst.mOperandSize = procType->mBase->mSize;
|
ins->mSrc[1].mTemp = inlineMapper->mResultExp->mTemp;
|
||||||
ains->mConst.mIntConst = 0;
|
ins->mSrc[1].mMemory = IM_INDIRECT;
|
||||||
ains->mConst.mVarIndex = inlineMapper->mResult;;
|
ins->mCode = IC_STORE;
|
||||||
ains->mConst.mMemory = IM_LOCAL;
|
ins->mSrc[1].mOperandSize = 2;
|
||||||
block->Append(ains);
|
ins->mNumOperands = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InterInstruction* ains = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||||
|
ains->mDst.mType = IT_POINTER;
|
||||||
|
ains->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
|
||||||
|
ains->mConst.mOperandSize = procType->mBase->mSize;
|
||||||
|
ains->mConst.mIntConst = 0;
|
||||||
|
ains->mConst.mVarIndex = inlineMapper->mResult;;
|
||||||
|
ains->mConst.mMemory = IM_LOCAL;
|
||||||
|
block->Append(ains);
|
||||||
|
|
||||||
ins->mSrc[1].mType = ains->mDst.mType;
|
ins->mSrc[1].mType = ains->mDst.mType;
|
||||||
ins->mSrc[1].mTemp = ains->mDst.mTemp;
|
ins->mSrc[1].mTemp = ains->mDst.mTemp;
|
||||||
ins->mSrc[1].mMemory = IM_INDIRECT;
|
ins->mSrc[1].mMemory = IM_INDIRECT;
|
||||||
ins->mCode = IC_STORE;
|
ins->mCode = IC_STORE;
|
||||||
ins->mSrc[1].mOperandSize = ains->mConst.mOperandSize;
|
ins->mSrc[1].mOperandSize = ains->mConst.mOperandSize;
|
||||||
ins->mNumOperands = 2;
|
ins->mNumOperands = 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2969,14 +3231,21 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
if (inlineMapper)
|
if (inlineMapper)
|
||||||
{
|
{
|
||||||
ains->mCode = IC_CONSTANT;
|
if (inlineMapper->mResultExp)
|
||||||
ains->mDst.mType = IT_POINTER;
|
{
|
||||||
ains->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
ains->mDst.mTemp = inlineMapper->mResultExp->mTemp;
|
||||||
ains->mConst.mOperandSize = procType->mBase->mSize;
|
}
|
||||||
ains->mConst.mIntConst = 0;
|
else
|
||||||
ains->mConst.mVarIndex = inlineMapper->mResult;
|
{
|
||||||
ains->mConst.mMemory = IM_LOCAL;
|
ains->mCode = IC_CONSTANT;
|
||||||
block->Append(ains);
|
ains->mDst.mType = IT_POINTER;
|
||||||
|
ains->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||||
|
ains->mConst.mOperandSize = procType->mBase->mSize;
|
||||||
|
ains->mConst.mIntConst = 0;
|
||||||
|
ains->mConst.mVarIndex = inlineMapper->mResult;
|
||||||
|
ains->mConst.mMemory = IM_LOCAL;
|
||||||
|
block->Append(ains);
|
||||||
|
}
|
||||||
|
|
||||||
ins->mCode = IC_NONE;
|
ins->mCode = IC_NONE;
|
||||||
}
|
}
|
||||||
|
@ -3009,20 +3278,102 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
ins->mCode = IC_RETURN;
|
ins->mCode = IC_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
InterInstruction* cins = new InterInstruction(exp->mLocation, IC_COPY);
|
CopyStruct(proc, exp, block, ExValue(procType->mBase, ains->mDst.mTemp), vr, inlineMapper);
|
||||||
cins->mSrc[0].mType = IT_POINTER;
|
#if 0
|
||||||
cins->mSrc[0].mTemp = vr.mTemp;
|
if (procType->mBase->mCopyConstructor)
|
||||||
cins->mSrc[0].mMemory = IM_INDIRECT;
|
{
|
||||||
cins->mSrc[0].mOperandSize = procType->mBase->mSize;
|
Declaration* ccdec = procType->mBase->mCopyConstructor;
|
||||||
cins->mSrc[0].mStride = vr.mType->mStripe;
|
if (ccdec->mBase->mFlags & DTF_FASTCALL)
|
||||||
|
{
|
||||||
|
if (!ccdec->mLinkerObject)
|
||||||
|
this->TranslateProcedure(proc->mModule, ccdec->mValue, ccdec);
|
||||||
|
|
||||||
cins->mSrc[1].mOperandSize = procType->mBase->mSize;
|
InterInstruction* psins = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||||
cins->mSrc[1].mType = IT_POINTER;
|
psins->mDst.mType = IT_POINTER;
|
||||||
cins->mSrc[1].mTemp = ains->mDst.mTemp;
|
psins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||||
cins->mSrc[1].mMemory = IM_INDIRECT;
|
psins->mConst.mVarIndex = 0;
|
||||||
|
psins->mConst.mIntConst = 0;
|
||||||
|
psins->mConst.mOperandSize = 2;
|
||||||
|
if (procType->mFlags & DTF_FASTCALL)
|
||||||
|
{
|
||||||
|
psins->mConst.mMemory = IM_FPARAM;
|
||||||
|
psins->mConst.mVarIndex += ccdec->mBase->mFastCallBase;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
psins->mConst.mMemory = IM_PARAM;
|
||||||
|
block->Append(psins);
|
||||||
|
|
||||||
cins->mConst.mOperandSize = procType->mBase->mSize;
|
InterInstruction* ssins = new InterInstruction(exp->mLocation, IC_STORE);
|
||||||
block->Append(cins);
|
ssins->mSrc[0] = ains->mDst;
|
||||||
|
ssins->mSrc[1] = psins->mDst;
|
||||||
|
block->Append(ssins);
|
||||||
|
|
||||||
|
InterInstruction* plins = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||||
|
plins->mDst.mType = IT_POINTER;
|
||||||
|
plins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||||
|
plins->mConst.mVarIndex = 2;
|
||||||
|
plins->mConst.mIntConst = 0;
|
||||||
|
plins->mConst.mOperandSize = 2;
|
||||||
|
if (procType->mFlags & DTF_FASTCALL)
|
||||||
|
{
|
||||||
|
plins->mConst.mMemory = IM_FPARAM;
|
||||||
|
plins->mConst.mVarIndex += ccdec->mBase->mFastCallBase;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
plins->mConst.mMemory = IM_PARAM;
|
||||||
|
block->Append(plins);
|
||||||
|
|
||||||
|
InterInstruction* slins = new InterInstruction(exp->mLocation, IC_STORE);
|
||||||
|
slins->mSrc[0].mType = IT_POINTER;
|
||||||
|
slins->mSrc[0].mTemp = vr.mTemp;
|
||||||
|
slins->mSrc[0].mMemory = IM_INDIRECT;
|
||||||
|
slins->mSrc[0].mOperandSize = procType->mBase->mSize;
|
||||||
|
slins->mSrc[0].mStride = vr.mType->mStripe;
|
||||||
|
slins->mSrc[1] = plins->mDst;
|
||||||
|
block->Append(slins);
|
||||||
|
|
||||||
|
proc->AddCalledFunction(proc->mModule->mProcedures[ccdec->mVarIndex]);
|
||||||
|
|
||||||
|
InterInstruction* pcins = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||||
|
pcins->mDst.mType = IT_POINTER;
|
||||||
|
pcins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||||
|
pcins->mConst.mType = IT_POINTER;
|
||||||
|
pcins->mConst.mVarIndex = ccdec->mVarIndex;
|
||||||
|
pcins->mConst.mIntConst = 0;
|
||||||
|
pcins->mConst.mOperandSize = 2;
|
||||||
|
pcins->mConst.mMemory = IM_GLOBAL;
|
||||||
|
pcins->mConst.mLinkerObject = ccdec->mLinkerObject;
|
||||||
|
block->Append(pcins);
|
||||||
|
|
||||||
|
InterInstruction* cins = new InterInstruction(exp->mLocation, IC_CALL);
|
||||||
|
if (ccdec->mFlags & DTF_NATIVE)
|
||||||
|
cins->mCode = IC_CALL_NATIVE;
|
||||||
|
else
|
||||||
|
cins->mCode = IC_CALL;
|
||||||
|
cins->mSrc[0] = pcins->mDst;
|
||||||
|
cins->mNumOperands = 1;
|
||||||
|
|
||||||
|
block->Append(cins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InterInstruction* cins = new InterInstruction(exp->mLocation, IC_COPY);
|
||||||
|
cins->mSrc[0].mType = IT_POINTER;
|
||||||
|
cins->mSrc[0].mTemp = vr.mTemp;
|
||||||
|
cins->mSrc[0].mMemory = IM_INDIRECT;
|
||||||
|
cins->mSrc[0].mOperandSize = procType->mBase->mSize;
|
||||||
|
cins->mSrc[0].mStride = vr.mType->mStripe;
|
||||||
|
|
||||||
|
cins->mSrc[1].mOperandSize = procType->mBase->mSize;
|
||||||
|
cins->mSrc[1].mType = IT_POINTER;
|
||||||
|
cins->mSrc[1].mTemp = ains->mDst.mTemp;
|
||||||
|
cins->mSrc[1].mMemory = IM_INDIRECT;
|
||||||
|
|
||||||
|
cins->mConst.mOperandSize = procType->mBase->mSize;
|
||||||
|
block->Append(cins);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3040,21 +3391,33 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
if (inlineMapper)
|
if (inlineMapper)
|
||||||
{
|
{
|
||||||
InterInstruction* ains = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
if (inlineMapper->mResultExp)
|
||||||
ains->mDst.mType = IT_POINTER;
|
{
|
||||||
ains->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
|
ins->mSrc[1].mType = IT_POINTER;
|
||||||
ains->mConst.mOperandSize = procType->mBase->mSize;
|
ins->mSrc[1].mTemp = inlineMapper->mResultExp->mTemp;
|
||||||
ains->mConst.mIntConst = 0;
|
ins->mSrc[1].mMemory = IM_INDIRECT;
|
||||||
ains->mConst.mVarIndex = inlineMapper->mResult;;
|
ins->mCode = IC_STORE;
|
||||||
ains->mConst.mMemory = IM_LOCAL;
|
ins->mSrc[1].mOperandSize = procType->mBase->mSize;
|
||||||
block->Append(ains);
|
ins->mNumOperands = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InterInstruction* ains = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||||
|
ains->mDst.mType = IT_POINTER;
|
||||||
|
ains->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
|
||||||
|
ains->mConst.mOperandSize = procType->mBase->mSize;
|
||||||
|
ains->mConst.mIntConst = 0;
|
||||||
|
ains->mConst.mVarIndex = inlineMapper->mResult;;
|
||||||
|
ains->mConst.mMemory = IM_LOCAL;
|
||||||
|
block->Append(ains);
|
||||||
|
|
||||||
ins->mSrc[1].mType = ains->mDst.mType;
|
ins->mSrc[1].mType = ains->mDst.mType;
|
||||||
ins->mSrc[1].mTemp = ains->mDst.mTemp;
|
ins->mSrc[1].mTemp = ains->mDst.mTemp;
|
||||||
ins->mSrc[1].mMemory = IM_INDIRECT;
|
ins->mSrc[1].mMemory = IM_INDIRECT;
|
||||||
ins->mCode = IC_STORE;
|
ins->mCode = IC_STORE;
|
||||||
ins->mSrc[1].mOperandSize = ains->mConst.mOperandSize;
|
ins->mSrc[1].mOperandSize = ains->mConst.mOperandSize;
|
||||||
ins->mNumOperands = 2;
|
ins->mNumOperands = 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3075,7 +3438,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
ins->mCode = IC_RETURN;
|
ins->mCode = IC_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
UnwindDestructStack(procType, proc, block, destack, nullptr);
|
UnwindDestructStack(procType, proc, block, destack, nullptr, inlineMapper);
|
||||||
|
|
||||||
if (ins->mCode != IC_NONE)
|
if (ins->mCode != IC_NONE)
|
||||||
block->Append(ins);
|
block->Append(ins);
|
||||||
|
@ -3097,7 +3460,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
{
|
{
|
||||||
if (breakBlock.mBlock)
|
if (breakBlock.mBlock)
|
||||||
{
|
{
|
||||||
UnwindDestructStack(procType, proc, block, destack, breakBlock.mStack);
|
UnwindDestructStack(procType, proc, block, destack, breakBlock.mStack, inlineMapper);
|
||||||
InterInstruction * jins = new InterInstruction(exp->mLocation, IC_JUMP);
|
InterInstruction * jins = new InterInstruction(exp->mLocation, IC_JUMP);
|
||||||
block->Append(jins);
|
block->Append(jins);
|
||||||
|
|
||||||
|
@ -3114,7 +3477,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
{
|
{
|
||||||
if (continueBlock.mBlock)
|
if (continueBlock.mBlock)
|
||||||
{
|
{
|
||||||
UnwindDestructStack(procType, proc, block, destack, continueBlock.mStack);
|
UnwindDestructStack(procType, proc, block, destack, continueBlock.mStack, inlineMapper);
|
||||||
InterInstruction * jins = new InterInstruction(exp->mLocation, IC_JUMP);
|
InterInstruction * jins = new InterInstruction(exp->mLocation, IC_JUMP);
|
||||||
block->Append(jins);
|
block->Append(jins);
|
||||||
|
|
||||||
|
@ -3508,7 +3871,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
|
TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
|
||||||
|
|
||||||
UnwindDestructStack(procType, proc, block, destack, odestack);
|
UnwindDestructStack(procType, proc, block, destack, odestack, inlineMapper);
|
||||||
destack = odestack;
|
destack = odestack;
|
||||||
|
|
||||||
return ExValue(TheVoidTypeDeclaration);
|
return ExValue(TheVoidTypeDeclaration);
|
||||||
|
@ -3536,7 +3899,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
vr = TranslateExpression(procType, proc, bblock, exp->mRight, destack, BranchTarget(eblock, odestack), BranchTarget(lblock, idestack), inlineMapper);
|
vr = TranslateExpression(procType, proc, bblock, exp->mRight, destack, BranchTarget(eblock, odestack), BranchTarget(lblock, idestack), inlineMapper);
|
||||||
|
|
||||||
UnwindDestructStack(procType, proc, bblock, destack, idestack);
|
UnwindDestructStack(procType, proc, bblock, destack, idestack, inlineMapper);
|
||||||
destack = idestack;
|
destack = idestack;
|
||||||
|
|
||||||
bblock->Append(jins1);
|
bblock->Append(jins1);
|
||||||
|
@ -3544,7 +3907,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
block = eblock;
|
block = eblock;
|
||||||
|
|
||||||
UnwindDestructStack(procType, proc, block, destack, odestack);
|
UnwindDestructStack(procType, proc, block, destack, odestack, inlineMapper);
|
||||||
destack = odestack;
|
destack = odestack;
|
||||||
|
|
||||||
return ExValue(TheVoidTypeDeclaration);
|
return ExValue(TheVoidTypeDeclaration);
|
||||||
|
@ -3565,7 +3928,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
DestructStack* itdestack = destack;
|
DestructStack* itdestack = destack;
|
||||||
vr = TranslateExpression(procType, proc, tblock, exp->mRight->mLeft, destack, breakBlock, continueBlock, inlineMapper);
|
vr = TranslateExpression(procType, proc, tblock, exp->mRight->mLeft, destack, breakBlock, continueBlock, inlineMapper);
|
||||||
UnwindDestructStack(procType, proc, tblock, destack, itdestack);
|
UnwindDestructStack(procType, proc, tblock, destack, itdestack, inlineMapper);
|
||||||
destack = itdestack;
|
destack = itdestack;
|
||||||
|
|
||||||
tblock->Append(jins0);
|
tblock->Append(jins0);
|
||||||
|
@ -3575,7 +3938,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
{
|
{
|
||||||
DestructStack* ifdestack = destack;
|
DestructStack* ifdestack = destack;
|
||||||
vr = TranslateExpression(procType, proc, fblock, exp->mRight->mRight, destack, breakBlock, continueBlock, inlineMapper);
|
vr = TranslateExpression(procType, proc, fblock, exp->mRight->mRight, destack, breakBlock, continueBlock, inlineMapper);
|
||||||
UnwindDestructStack(procType, proc, fblock, destack, ifdestack);
|
UnwindDestructStack(procType, proc, fblock, destack, ifdestack, inlineMapper);
|
||||||
destack = ifdestack;
|
destack = ifdestack;
|
||||||
}
|
}
|
||||||
fblock->Append(jins1);
|
fblock->Append(jins1);
|
||||||
|
@ -3583,7 +3946,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
block = eblock;
|
block = eblock;
|
||||||
|
|
||||||
UnwindDestructStack(procType, proc, block, destack, odestack);
|
UnwindDestructStack(procType, proc, block, destack, odestack, inlineMapper);
|
||||||
destack = odestack;
|
destack = odestack;
|
||||||
|
|
||||||
return ExValue(TheVoidTypeDeclaration);
|
return ExValue(TheVoidTypeDeclaration);
|
||||||
|
@ -3626,7 +3989,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
vr = TranslateExpression(procType, proc, bblock, exp->mRight, destack, BranchTarget(eblock, odestack), BranchTarget(iblock, idestack), inlineMapper);
|
vr = TranslateExpression(procType, proc, bblock, exp->mRight, destack, BranchTarget(eblock, odestack), BranchTarget(iblock, idestack), inlineMapper);
|
||||||
|
|
||||||
UnwindDestructStack(procType, proc, bblock, destack, idestack);
|
UnwindDestructStack(procType, proc, bblock, destack, idestack, inlineMapper);
|
||||||
destack = idestack;
|
destack = idestack;
|
||||||
|
|
||||||
bblock->Append(jins2);
|
bblock->Append(jins2);
|
||||||
|
@ -3641,7 +4004,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
block = eblock;
|
block = eblock;
|
||||||
|
|
||||||
UnwindDestructStack(procType, proc, block, destack, odestack);
|
UnwindDestructStack(procType, proc, block, destack, odestack, inlineMapper);
|
||||||
destack = odestack;
|
destack = odestack;
|
||||||
|
|
||||||
return ExValue(TheVoidTypeDeclaration);
|
return ExValue(TheVoidTypeDeclaration);
|
||||||
|
@ -3664,14 +4027,14 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
vr = TranslateExpression(procType, proc, cblock, exp->mRight, destack, BranchTarget(eblock, odestack), BranchTarget(cblock, idestack), inlineMapper);
|
vr = TranslateExpression(procType, proc, cblock, exp->mRight, destack, BranchTarget(eblock, odestack), BranchTarget(cblock, idestack), inlineMapper);
|
||||||
|
|
||||||
UnwindDestructStack(procType, proc, cblock, destack, idestack);
|
UnwindDestructStack(procType, proc, cblock, destack, idestack, inlineMapper);
|
||||||
destack = idestack;
|
destack = idestack;
|
||||||
|
|
||||||
TranslateLogic(procType, proc, cblock, lblock, eblock, exp->mLeft, destack, inlineMapper);
|
TranslateLogic(procType, proc, cblock, lblock, eblock, exp->mLeft, destack, inlineMapper);
|
||||||
|
|
||||||
block = eblock;
|
block = eblock;
|
||||||
|
|
||||||
UnwindDestructStack(procType, proc, block, destack, odestack);
|
UnwindDestructStack(procType, proc, block, destack, odestack, inlineMapper);
|
||||||
destack = odestack;
|
destack = odestack;
|
||||||
|
|
||||||
return ExValue(TheVoidTypeDeclaration);
|
return ExValue(TheVoidTypeDeclaration);
|
||||||
|
@ -3759,7 +4122,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
if (block)
|
if (block)
|
||||||
{
|
{
|
||||||
UnwindDestructStack(procType, proc, block, destack, odestack);
|
UnwindDestructStack(procType, proc, block, destack, odestack, inlineMapper);
|
||||||
|
|
||||||
InterInstruction* jins = new InterInstruction(exp->mLocation, IC_JUMP);
|
InterInstruction* jins = new InterInstruction(exp->mLocation, IC_JUMP);
|
||||||
|
|
||||||
|
@ -3962,6 +4325,11 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
|
||||||
{
|
{
|
||||||
InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mQualIdent, mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_BYTE_CODE));
|
InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mQualIdent, mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_BYTE_CODE));
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (proc->mIdent && !strcmp(proc->mIdent->mString, "test_retparam_value"))
|
||||||
|
exp->Dump(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
uint64 outerCompilerOptions = mCompilerOptions;
|
uint64 outerCompilerOptions = mCompilerOptions;
|
||||||
mCompilerOptions = dec->mCompilerOptions;
|
mCompilerOptions = dec->mCompilerOptions;
|
||||||
|
|
||||||
|
@ -4050,7 +4418,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
|
||||||
|
|
||||||
TranslateExpression(dec->mBase, proc, exitBlock, exp, destack, BranchTarget(), BranchTarget(), nullptr);
|
TranslateExpression(dec->mBase, proc, exitBlock, exp, destack, BranchTarget(), BranchTarget(), nullptr);
|
||||||
|
|
||||||
UnwindDestructStack(dec->mBase, proc, exitBlock, destack, nullptr);
|
UnwindDestructStack(dec->mBase, proc, exitBlock, destack, nullptr, nullptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mQualIdent->mString);
|
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mQualIdent->mString);
|
||||||
|
|
|
@ -59,9 +59,10 @@ protected:
|
||||||
InterCodeBasicBlock * mReturn;
|
InterCodeBasicBlock * mReturn;
|
||||||
int mResult, mDepth, mVarIndex;
|
int mResult, mDepth, mVarIndex;
|
||||||
bool mConstExpr;
|
bool mConstExpr;
|
||||||
|
ExValue * mResultExp;
|
||||||
|
|
||||||
InlineMapper(void)
|
InlineMapper(void)
|
||||||
: mParams(-1), mResult(-1), mDepth(0)
|
: mParams(-1), mResult(-1), mDepth(0), mResultExp(nullptr)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,8 +80,9 @@ protected:
|
||||||
ExValue CoerceType(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v, Declaration * type, bool checkTrunc = true);
|
ExValue CoerceType(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v, Declaration * type, bool checkTrunc = true);
|
||||||
ExValue TranslateExpression(Declaration * procType, InterCodeProcedure * proc, InterCodeBasicBlock*& block, Expression* exp, DestructStack*& destack, const BranchTarget & breakBlock, const BranchTarget& continueBlock, InlineMapper * inlineMapper, ExValue * lrexp = nullptr);
|
ExValue TranslateExpression(Declaration * procType, InterCodeProcedure * proc, InterCodeBasicBlock*& block, Expression* exp, DestructStack*& destack, const BranchTarget & breakBlock, const BranchTarget& continueBlock, InlineMapper * inlineMapper, ExValue * lrexp = nullptr);
|
||||||
void TranslateLogic(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock* block, InterCodeBasicBlock* tblock, InterCodeBasicBlock* fblock, Expression* exp, DestructStack*& destack, InlineMapper* inlineMapper);
|
void TranslateLogic(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock* block, InterCodeBasicBlock* tblock, InterCodeBasicBlock* fblock, Expression* exp, DestructStack*& destack, InlineMapper* inlineMapper);
|
||||||
ExValue TranslateInline(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, const BranchTarget& breakBlock, const BranchTarget& continueBlock, InlineMapper* inlineMapper, bool inlineConstexpr);
|
ExValue TranslateInline(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, const BranchTarget& breakBlock, const BranchTarget& continueBlock, InlineMapper* inlineMapper, bool inlineConstexpr, ExValue* lrexp);
|
||||||
|
void CopyStruct(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue vl, ExValue vr, InlineMapper* inlineMapper);
|
||||||
|
|
||||||
void UnwindDestructStack(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, DestructStack* stack, DestructStack * bottom);
|
void UnwindDestructStack(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, DestructStack* stack, DestructStack * bottom, InlineMapper* inlineMapper);
|
||||||
void BuildInitializer(InterCodeModule* mod, uint8 * dp, int offset, Declaration* data, InterVariable * variable);
|
void BuildInitializer(InterCodeModule* mod, uint8 * dp, int offset, Declaration* data, InterVariable * variable);
|
||||||
};
|
};
|
||||||
|
|
|
@ -34621,6 +34621,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_INX &&
|
mIns[i + 0].mType == ASMIT_INX &&
|
||||||
mIns[i + 1].mType == ASMIT_DEX && !(mIns[i + 1].mLive & LIVE_CPU_REG_Z))
|
mIns[i + 1].mType == ASMIT_DEX && !(mIns[i + 1].mLive & LIVE_CPU_REG_Z))
|
||||||
|
@ -34654,6 +34655,39 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_LDX && mIns[i + 0].mMode == ASMIM_IMMEDIATE &&
|
||||||
|
mIns[i + 1].mType == ASMIT_DEX)
|
||||||
|
{
|
||||||
|
mIns[i + 0].mAddress = (mIns[i + 0].mAddress - 1) & 255;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_LDX && mIns[i + 0].mMode == ASMIM_IMMEDIATE &&
|
||||||
|
mIns[i + 1].mType == ASMIT_INX)
|
||||||
|
{
|
||||||
|
mIns[i + 0].mAddress = (mIns[i + 0].mAddress + 1) & 255;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE &&
|
||||||
|
mIns[i + 1].mType == ASMIT_DEY)
|
||||||
|
{
|
||||||
|
mIns[i + 0].mAddress = (mIns[i + 0].mAddress - 1) & 255;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE &&
|
||||||
|
mIns[i + 1].mType == ASMIT_INY)
|
||||||
|
{
|
||||||
|
mIns[i + 0].mAddress = (mIns[i + 0].mAddress + 1) & 255;
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_IMMEDIATE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ABSOLUTE_X) &&
|
mIns[i + 0].mType == ASMIT_LDA && (mIns[i + 0].mMode == ASMIM_IMMEDIATE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ABSOLUTE_X) &&
|
||||||
mIns[i + 1].mType == ASMIT_TAY && !(mIns[i + 1].mLive & LIVE_CPU_REG_A))
|
mIns[i + 1].mType == ASMIT_TAY && !(mIns[i + 1].mLive & LIVE_CPU_REG_A))
|
||||||
|
@ -34952,7 +34986,10 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
||||||
if (FindPageStartAddress(i, mIns[i + 1].mAddress, addr))
|
if (FindPageStartAddress(i, mIns[i + 1].mAddress, addr))
|
||||||
{
|
{
|
||||||
if (mIns[i + 1].mLive & LIVE_CPU_REG_Y)
|
if (mIns[i + 1].mLive & LIVE_CPU_REG_Y)
|
||||||
|
{
|
||||||
mIns.Insert(i + 2, mIns[i + 0]);
|
mIns.Insert(i + 2, mIns[i + 0]);
|
||||||
|
mIns[i + 2].mLive |= mIns[i + 1].mLive;
|
||||||
|
}
|
||||||
|
|
||||||
int absaddr = addr + mIns[i + 0].mAddress;
|
int absaddr = addr + mIns[i + 0].mAddress;
|
||||||
|
|
||||||
|
@ -39997,7 +40034,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
{
|
{
|
||||||
mInterProc = proc;
|
mInterProc = proc;
|
||||||
|
|
||||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "mapTimeTick");
|
CheckFunc = !strcmp(mInterProc->mIdent->mString, "Y::Y");
|
||||||
|
|
||||||
int nblocks = proc->mBlocks.Size();
|
int nblocks = proc->mBlocks.Size();
|
||||||
tblocks = new NativeCodeBasicBlock * [nblocks];
|
tblocks = new NativeCodeBasicBlock * [nblocks];
|
||||||
|
@ -41273,7 +41310,6 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
|
|
||||||
} while (changed);
|
} while (changed);
|
||||||
|
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->ReduceLocalYPressure();
|
mEntryBlock->ReduceLocalYPressure();
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -46,6 +46,13 @@ protected:
|
||||||
Expression* BuildMemberInitializer(Expression* vexp);
|
Expression* BuildMemberInitializer(Expression* vexp);
|
||||||
void PrependMemberConstructor(Declaration* pthis, Declaration* cfunc);
|
void PrependMemberConstructor(Declaration* pthis, Declaration* cfunc);
|
||||||
|
|
||||||
|
void AddDefaultConstructors(Declaration* pthis);
|
||||||
|
|
||||||
|
void ParseVariableInit(Declaration* ndec);
|
||||||
|
|
||||||
|
Expression * AddFunctionCallRefReturned(Expression * exp);
|
||||||
|
Expression* CleanupExpression(Expression* exp);
|
||||||
|
|
||||||
Declaration* ParseBaseTypeDeclaration(uint64 flags);
|
Declaration* ParseBaseTypeDeclaration(uint64 flags);
|
||||||
Declaration* ParseDeclaration(Declaration* pdec, bool variable, bool expression, Declaration * pthis = nullptr);
|
Declaration* ParseDeclaration(Declaration* pdec, bool variable, bool expression, Declaration * pthis = nullptr);
|
||||||
Declaration* ParseStructDeclaration(uint64 flags, DecType dt);
|
Declaration* ParseStructDeclaration(uint64 flags, DecType dt);
|
||||||
|
@ -65,6 +72,8 @@ protected:
|
||||||
Expression* ParseAssemblerAddOperand(Declaration* pcasm, int pcoffset);
|
Expression* ParseAssemblerAddOperand(Declaration* pcasm, int pcoffset);
|
||||||
Expression* ParseAssemblerOperand(Declaration * pcasm, int pcoffset);
|
Expression* ParseAssemblerOperand(Declaration * pcasm, int pcoffset);
|
||||||
|
|
||||||
|
Expression* CheckOperatorOverload(Expression* exp);
|
||||||
|
|
||||||
void AddAssemblerRegister(const Ident* ident, int value);
|
void AddAssemblerRegister(const Ident* ident, int value);
|
||||||
|
|
||||||
Declaration* ParseQualIdent(void);
|
Declaration* ParseQualIdent(void);
|
||||||
|
|
|
@ -1394,6 +1394,17 @@ void Scanner::NextRawToken(void)
|
||||||
mToken = TK_USING;
|
mToken = TK_USING;
|
||||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "this"))
|
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "this"))
|
||||||
mToken = TK_THIS;
|
mToken = TK_THIS;
|
||||||
|
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "operator"))
|
||||||
|
{
|
||||||
|
NextRawToken();
|
||||||
|
if (mToken == TK_ASSIGN)
|
||||||
|
{
|
||||||
|
mToken = TK_IDENT;
|
||||||
|
mTokenIdent = Ident::Unique("operator=");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(mLocation, EERR_INVALID_OPERATOR, "Invalid operator token");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mToken = TK_IDENT;
|
mToken = TK_IDENT;
|
||||||
|
|
Loading…
Reference in New Issue