Fix class member array initialization
This commit is contained in:
parent
381aaa1509
commit
7efd512ee9
|
@ -18,6 +18,9 @@ rem @echo off
|
|||
@call :testh opp_vector_string.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_string_init.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_streamtest.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
#include <opp/string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
using opp::string;
|
||||
|
||||
|
||||
const string s1;
|
||||
const string s2 = "Hello";
|
||||
const string s3{"World"};
|
||||
|
||||
const string a1[2];
|
||||
const string a2[2] = {"Hello", "World"};
|
||||
const string a3[2] = {opp::string("Hello"), opp::string("World")};
|
||||
|
||||
|
||||
const string d1[3][2];
|
||||
const string d2[3][2] = {{"Hello", "World"}, {"aaa", "bbb"}, {"ccc", "ddd"}};
|
||||
const string d3[3][2] =
|
||||
{{opp::string("Hello"), opp::string("World")},
|
||||
{opp::string("aaa"), opp::string("bbb")},
|
||||
{opp::string("ccc"), opp::string("ddd")}};
|
||||
|
||||
void test_global_init(void)
|
||||
{
|
||||
assert(!strcmp(s1.tocstr(), ""));
|
||||
assert(!strcmp(s2.tocstr(), "Hello"));
|
||||
assert(!strcmp(s3.tocstr(), "World"));
|
||||
}
|
||||
|
||||
|
||||
void test_global_ainit(void)
|
||||
{
|
||||
assert(!strcmp(a1[0].tocstr(), ""));
|
||||
assert(!strcmp(a1[1].tocstr(), ""));
|
||||
|
||||
assert(!strcmp(a2[0].tocstr(), "Hello"));
|
||||
assert(!strcmp(a2[1].tocstr(), "World"));
|
||||
|
||||
assert(!strcmp(a3[0].tocstr(), "Hello"));
|
||||
assert(!strcmp(a3[1].tocstr(), "World"));
|
||||
}
|
||||
|
||||
void test_global_dinit(void)
|
||||
{
|
||||
assert(!strcmp(d1[0][0].tocstr(), ""));
|
||||
assert(!strcmp(d1[2][1].tocstr(), ""));
|
||||
|
||||
assert(!strcmp(d2[0][0].tocstr(), "Hello"));
|
||||
assert(!strcmp(d2[2][1].tocstr(), "ddd"));
|
||||
|
||||
assert(!strcmp(d3[0][0].tocstr(), "Hello"));
|
||||
assert(!strcmp(d3[2][1].tocstr(), "ddd"));
|
||||
}
|
||||
|
||||
|
||||
void test_local_init(void)
|
||||
{
|
||||
const string s1;
|
||||
const string s2 = "Hello";
|
||||
const string s3{"World"};
|
||||
|
||||
assert(!strcmp(s1.tocstr(), ""));
|
||||
assert(!strcmp(s2.tocstr(), "Hello"));
|
||||
assert(!strcmp(s3.tocstr(), "World"));
|
||||
}
|
||||
|
||||
|
||||
void test_local_ainit(void)
|
||||
{
|
||||
const string a1[2];
|
||||
const string a2[2] = {"Hello", "World"};
|
||||
const string a3[2] = {opp::string("Hello"), opp::string("World")};
|
||||
|
||||
assert(!strcmp(a1[0].tocstr(), ""));
|
||||
assert(!strcmp(a1[1].tocstr(), ""));
|
||||
|
||||
assert(!strcmp(a2[0].tocstr(), "Hello"));
|
||||
assert(!strcmp(a2[1].tocstr(), "World"));
|
||||
|
||||
assert(!strcmp(a3[0].tocstr(), "Hello"));
|
||||
assert(!strcmp(a3[1].tocstr(), "World"));
|
||||
}
|
||||
|
||||
void test_local_dinit(void)
|
||||
{
|
||||
const string d1[3][2];
|
||||
const string d2[3][2] = {{"Hello", "World"}, {"aaa", "bbb"}, {"ccc", "ddd"}};
|
||||
const string d3[3][2] =
|
||||
{{opp::string("Hello"), opp::string("World")},
|
||||
{opp::string("aaa"), opp::string("bbb")},
|
||||
{opp::string("ccc"), opp::string("ddd")}};
|
||||
|
||||
assert(!strcmp(d1[0][0].tocstr(), ""));
|
||||
assert(!strcmp(d1[2][1].tocstr(), ""));
|
||||
|
||||
assert(!strcmp(d2[0][0].tocstr(), "Hello"));
|
||||
assert(!strcmp(d2[2][1].tocstr(), "ddd"));
|
||||
|
||||
assert(!strcmp(d3[0][0].tocstr(), "Hello"));
|
||||
assert(!strcmp(d3[2][1].tocstr(), "ddd"));
|
||||
}
|
||||
|
||||
class X
|
||||
{
|
||||
public:
|
||||
const string s1;
|
||||
const string s2 = "Hello";
|
||||
const string s3;
|
||||
|
||||
const string a1[2];
|
||||
const string a2[2] = {"Hello", "World"};
|
||||
|
||||
const string d1[3][2];
|
||||
const string d2[3][2] = {{"Hello", "World"}, {"aaa", "bbb"}, {"ccc", "ddd"}};
|
||||
|
||||
X() : s3("World") {}
|
||||
};
|
||||
|
||||
void test_member_init(void)
|
||||
{
|
||||
X x;
|
||||
|
||||
assert(!strcmp(x.s1.tocstr(), ""));
|
||||
assert(!strcmp(x.s2.tocstr(), "Hello"));
|
||||
assert(!strcmp(x.s3.tocstr(), "World"));
|
||||
}
|
||||
|
||||
void test_member_ainit(void)
|
||||
{
|
||||
X x;
|
||||
|
||||
assert(!strcmp(x.a1[0].tocstr(), ""));
|
||||
assert(!strcmp(x.a1[1].tocstr(), ""));
|
||||
|
||||
assert(!strcmp(x.a2[0].tocstr(), "Hello"));
|
||||
assert(!strcmp(x.a2[1].tocstr(), "World"));
|
||||
}
|
||||
|
||||
void test_member_dinit(void)
|
||||
{
|
||||
X x;
|
||||
|
||||
assert(!strcmp(x.d1[0][0].tocstr(), ""));
|
||||
assert(!strcmp(x.d1[2][1].tocstr(), ""));
|
||||
|
||||
assert(!strcmp(x.d2[0][0].tocstr(), "Hello"));
|
||||
assert(!strcmp(x.d2[2][1].tocstr(), "ddd"));
|
||||
}
|
||||
|
||||
void test_copy_init(void)
|
||||
{
|
||||
X x;
|
||||
X y(x);
|
||||
|
||||
assert(!strcmp(y.s1.tocstr(), ""));
|
||||
assert(!strcmp(y.s2.tocstr(), "Hello"));
|
||||
assert(!strcmp(y.s3.tocstr(), "World"));
|
||||
}
|
||||
|
||||
void test_copy_ainit(void)
|
||||
{
|
||||
X x;
|
||||
X y(x);
|
||||
|
||||
assert(!strcmp(y.a1[0].tocstr(), ""));
|
||||
assert(!strcmp(y.a1[1].tocstr(), ""));
|
||||
|
||||
assert(!strcmp(y.a2[0].tocstr(), "Hello"));
|
||||
assert(!strcmp(y.a2[1].tocstr(), "World"));
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
test_global_init();
|
||||
test_global_ainit();
|
||||
test_global_dinit();
|
||||
|
||||
for(int i=0; i<10000; i++)
|
||||
{
|
||||
test_local_init();
|
||||
test_local_ainit();
|
||||
}
|
||||
|
||||
test_member_init();
|
||||
test_member_ainit();
|
||||
|
||||
test_copy_init();
|
||||
test_copy_ainit();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -147,7 +147,8 @@ void DeclarationScope::End(const Location& loc)
|
|||
Expression::Expression(const Location& loc, ExpressionType type)
|
||||
: mLocation(loc), mEndLocation(loc), mType(type), mLeft(nullptr), mRight(nullptr), mConst(false), mDecType(nullptr), mDecValue(nullptr), mToken(TK_NONE)
|
||||
{
|
||||
|
||||
static uint32 gUID = 0;
|
||||
mUID = gUID++;
|
||||
}
|
||||
|
||||
Expression::~Expression(void)
|
||||
|
@ -1106,7 +1107,10 @@ Declaration::Declaration(const Location& loc, DecType type)
|
|||
mCompilerOptions(0), mUseCount(0), mTokens(nullptr), mParser(nullptr),
|
||||
mShift(0), mBits(0), mOptFlags(0), mInlayRegion(nullptr),
|
||||
mReferences(nullptr)
|
||||
{}
|
||||
{
|
||||
static uint32 gUID = 0;
|
||||
mUID = gUID++;
|
||||
}
|
||||
|
||||
Declaration::~Declaration(void)
|
||||
{
|
||||
|
@ -2091,6 +2095,7 @@ Declaration* Declaration::ToVolatileType(void)
|
|||
ndec->mCopyConstructor = mCopyConstructor;
|
||||
ndec->mMoveConstructor = mMoveConstructor;
|
||||
ndec->mVectorConstructor = mVectorConstructor;
|
||||
ndec->mVectorDestructor = mVectorDestructor;
|
||||
ndec->mVectorCopyConstructor = mVectorCopyConstructor;
|
||||
ndec->mVTable = mVTable;
|
||||
|
||||
|
@ -2123,6 +2128,7 @@ Declaration* Declaration::ToConstType(void)
|
|||
ndec->mCopyConstructor = mCopyConstructor;
|
||||
ndec->mMoveConstructor = mMoveConstructor;
|
||||
ndec->mVectorConstructor = mVectorConstructor;
|
||||
ndec->mVectorDestructor = mVectorDestructor;
|
||||
ndec->mVectorCopyConstructor = mVectorCopyConstructor;
|
||||
ndec->mVTable = mVTable;
|
||||
|
||||
|
@ -2156,6 +2162,7 @@ Declaration* Declaration::ToMutableType(void)
|
|||
ndec->mCopyConstructor = mCopyConstructor;
|
||||
ndec->mMoveConstructor = mMoveConstructor;
|
||||
ndec->mVectorConstructor = mVectorConstructor;
|
||||
ndec->mVectorDestructor = mVectorDestructor;
|
||||
ndec->mVectorCopyConstructor = mVectorCopyConstructor;
|
||||
ndec->mVTable = mVTable;
|
||||
|
||||
|
|
|
@ -242,6 +242,8 @@ public:
|
|||
Expression(const Location& loc, ExpressionType type);
|
||||
~Expression(void);
|
||||
|
||||
uint32 mUID;
|
||||
|
||||
Location mLocation, mEndLocation;
|
||||
ExpressionType mType;
|
||||
Expression * mLeft, * mRight;
|
||||
|
@ -270,6 +272,8 @@ public:
|
|||
Declaration(const Location & loc, DecType type);
|
||||
~Declaration(void);
|
||||
|
||||
uint32 mUID;
|
||||
|
||||
Location mLocation, mEndLocation;
|
||||
DecType mType;
|
||||
Token mToken;
|
||||
|
|
|
@ -538,6 +538,7 @@ int Emulator::Emulate(int startIP, int trace)
|
|||
mMemory[0x1ff] = 0xff;
|
||||
|
||||
int tcycles = 0, cycles = 0;
|
||||
int iip = 0;
|
||||
while (mIP != 0)
|
||||
{
|
||||
if (mJiffies)
|
||||
|
@ -584,7 +585,10 @@ int Emulator::Emulate(int startIP, int trace)
|
|||
AsmInsData d = DecInsData[opcode];
|
||||
int addr = 0, taddr;
|
||||
int ip = mIP;
|
||||
int iip = mMemory[BC_REG_IP] + 256 * mMemory[BC_REG_IP + 1];
|
||||
|
||||
if (ip == 0x0862)
|
||||
iip = mMemory[BC_REG_IP] + 256 * mMemory[BC_REG_IP + 1] + mRegY;
|
||||
|
||||
bool cross = false, indexed = false;
|
||||
int icycles = 0;
|
||||
|
||||
|
|
|
@ -110,6 +110,7 @@ enum ErrorID
|
|||
EERR_ASSEMBLER_LIMIT,
|
||||
|
||||
EERR_INVALID_PREPROCESSOR,
|
||||
EERR_INVALID_CLASS_INITIALIZER,
|
||||
|
||||
EFATAL_GENERIC = 4000,
|
||||
EFATAL_OUT_OF_MEMORY,
|
||||
|
|
|
@ -21975,7 +21975,7 @@ void InterCodeProcedure::Close(void)
|
|||
{
|
||||
GrowingTypeArray tstack(IT_NONE);
|
||||
|
||||
CheckFunc = !strcmp(mIdent->mString, "main");
|
||||
CheckFunc = !strcmp(mIdent->mString, "test");
|
||||
CheckCase = false;
|
||||
|
||||
mEntryBlock = mBlocks[0];
|
||||
|
@ -23819,7 +23819,7 @@ void InterCodeProcedure::Disassemble(FILE* file)
|
|||
|
||||
void InterCodeProcedure::Disassemble(const char* name, bool dumpSets)
|
||||
{
|
||||
#if 0
|
||||
#if 1
|
||||
#ifdef _WIN32
|
||||
FILE* file;
|
||||
static bool initial = true;
|
||||
|
|
|
@ -719,6 +719,8 @@ void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration*
|
|||
{
|
||||
DestructStack* destack = nullptr;
|
||||
GotoNode* gotos = nullptr;
|
||||
dec->mValue->mRight->mDecValue = dec;
|
||||
dec->mLinkerObject->mFlags &= ~LOBJF_CONST;
|
||||
TranslateExpression(nullptr, mMainInitProc, mMainInitBlock, dec->mValue, destack, gotos, BranchTarget(), BranchTarget(), nullptr);
|
||||
}
|
||||
else if (dec->mValue->mType == EX_VARIABLE && dec->mValue->mDecType->mType == DT_TYPE_ARRAY && dec->mBase->mType == DT_TYPE_POINTER && dec->mBase->CanAssign(dec->mValue->mDecType))
|
||||
|
@ -2200,6 +2202,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
var->mLinkerObject->mVariable = var;
|
||||
dec->mLinkerObject = var->mLinkerObject;
|
||||
var->mIdent = dec->mQualIdent;
|
||||
var->mDeclaration = dec;
|
||||
dec->mVarIndex = proc->mModule->mGlobalVars.Size();
|
||||
var->mIndex = dec->mVarIndex;
|
||||
proc->mModule->mGlobalVars.Push(var);
|
||||
|
@ -2281,7 +2284,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ins->mConst.mOperandSize = 2;
|
||||
}
|
||||
}
|
||||
else if (dec->mFlags & DTF_GLOBAL)
|
||||
else if (dec->mType == DT_CONST_STRUCT || (dec->mFlags & DTF_GLOBAL))
|
||||
{
|
||||
InitGlobalVariable(proc->mModule, dec);
|
||||
ins->mConst.mMemory = IM_GLOBAL;
|
||||
|
@ -2351,7 +2354,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
|
||||
if (exp->mType == EX_INITIALIZATION && exp->mRight->mType == EX_CONSTANT && exp->mRight->mDecValue && exp->mRight->mDecValue->mLinkerObject)
|
||||
{
|
||||
exp->mRight->mDecValue->mLinkerObject->mFlags |= LOBJF_CONST;
|
||||
if (!(exp->mRight->mDecValue->mFlags & DTF_VAR_ALIASING))
|
||||
exp->mRight->mDecValue->mLinkerObject->mFlags |= LOBJF_CONST;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2661,9 +2665,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
block->Append(ains);
|
||||
|
||||
if (exp->mDecType->IsReference())
|
||||
return ExValue(exp->mDecValue->mBase->mBase, ains->mDst.mTemp, 2);
|
||||
return ExValue(exp->mDecType->mBase, ains->mDst.mTemp, 2);
|
||||
else
|
||||
return ExValue(exp->mDecValue->mBase, ains->mDst.mTemp, 1, exp->mDecValue->mBits, exp->mDecValue->mShift);
|
||||
return ExValue(exp->mDecType, ains->mDst.mTemp, 1, exp->mDecValue->mBits, exp->mDecValue->mShift);
|
||||
}
|
||||
|
||||
case EX_BINARY:
|
||||
|
@ -2689,7 +2693,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ptype->mSize = 2;
|
||||
ptype->mStride = vl.mType->mStride;
|
||||
vl.mReference = 0;
|
||||
vl.mType = ptype;
|
||||
vl.mType = exp->mDecType; // ptype;
|
||||
}
|
||||
|
||||
if (vr.mType->mType == DT_TYPE_POINTER)
|
||||
|
@ -3184,7 +3188,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
dec->mBase = vl.mType;
|
||||
dec->mSize = 2;
|
||||
dec->mFlags = DTF_DEFINED;
|
||||
return ExValue(dec, vl.mTemp, vl.mReference - 1);
|
||||
return ExValue(exp->mDecType, vl.mTemp, vl.mReference - 1);
|
||||
}
|
||||
case TK_BANKOF:
|
||||
{
|
||||
|
@ -5427,6 +5431,17 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
|
|||
{
|
||||
assert(false);
|
||||
}
|
||||
else if (data->mType == DT_CONST_CONSTRUCTOR)
|
||||
{
|
||||
Declaration* dec = new Declaration(data->mLocation, DT_VARIABLE_REF);
|
||||
dec->mBase = variable->mDeclaration;
|
||||
dec->mOffset = offset;
|
||||
DestructStack* destack = nullptr;
|
||||
GotoNode* gotos = nullptr;
|
||||
data->mValue->mRight->mDecValue = dec;
|
||||
dec->mBase->mFlags |= DTF_VAR_ALIASING;
|
||||
TranslateExpression(nullptr, mMainInitProc, mMainInitBlock, data->mValue, destack, gotos, BranchTarget(), BranchTarget(), nullptr);
|
||||
}
|
||||
else if (data->mType == DT_CONST_POINTER)
|
||||
{
|
||||
Expression* exp = data->mValue;
|
||||
|
|
|
@ -45632,7 +45632,9 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerIterate4(int i, int pass)
|
|||
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||
mIns[i + 2].mType == ASMIT_LDX && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress == mIns[i + 0].mAddress &&
|
||||
mIns[i + 3].mType == ASMIT_STX && mIns[i + 3].mMode == ASMIM_ZERO_PAGE &&
|
||||
!mIns[i + 1].ChangesZeroPage(mIns[i + 0].mAddress) && !mIns[i + 1].UsesZeroPage(mIns[i + 3].mAddress))
|
||||
!mIns[i + 1].ChangesZeroPage(mIns[i + 0].mAddress) &&
|
||||
!mIns[i + 1].UsesZeroPage(mIns[i + 3].mAddress) &&
|
||||
!mIns[i + 1].ChangesZeroPage(mIns[i + 3].mAddress))
|
||||
{
|
||||
mIns[i + 0].mLive |= LIVE_CPU_REG_A;
|
||||
|
||||
|
@ -50683,7 +50685,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
|||
mInterProc = proc;
|
||||
mInterProc->mLinkerObject->mNativeProc = this;
|
||||
|
||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "sqrt");
|
||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "test");
|
||||
|
||||
int nblocks = proc->mBlocks.Size();
|
||||
tblocks = new NativeCodeBasicBlock * [nblocks];
|
||||
|
@ -51597,7 +51599,6 @@ void NativeCodeProcedure::Optimize(void)
|
|||
} while (changed && t < 20);
|
||||
#endif
|
||||
|
||||
|
||||
BuildDataFlowSets();
|
||||
ResetVisited();
|
||||
mEntryBlock->RemoveUnusedResultInstructions();
|
||||
|
@ -52495,6 +52496,7 @@ void NativeCodeProcedure::Optimize(void)
|
|||
else
|
||||
cnt++;
|
||||
|
||||
|
||||
} while (changed);
|
||||
|
||||
#if 1
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -56,7 +56,9 @@ protected:
|
|||
|
||||
void AddDefaultConstructors(Declaration* pthis);
|
||||
|
||||
void ParseVariableInit(Declaration* ndec);
|
||||
Expression* BuildVariableArrayInit(Expression* texp, Declaration* bpdec, Declaration* pdec, int boffset, int & offset);
|
||||
Expression * BuildVariableInit(Expression* vexp, Expression* pexp);
|
||||
void ParseVariableInit(Declaration* ndec, Expression * pexp = nullptr);
|
||||
Declaration* AddMemberFunction(Declaration* dec, Declaration* mdec);
|
||||
Declaration* FindBaseMemberFunction(Declaration* dec, Declaration* mdec);
|
||||
|
||||
|
|
Loading…
Reference in New Issue