Add autotest for string stream
This commit is contained in:
parent
fbde581475
commit
9b2d90ec58
|
@ -3,6 +3,9 @@ rem @echo off
|
||||||
@call :test opp_string.cpp
|
@call :test opp_string.cpp
|
||||||
@if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
@call :test opp_streamtest.cpp
|
||||||
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
@call :test operatoroverload.cpp
|
@call :test operatoroverload.cpp
|
||||||
@if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
#include <opp/string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <opp/sstream.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
float fdist(float a, float b)
|
||||||
|
{
|
||||||
|
float d = fabs(a - b);
|
||||||
|
a = fabs(a);
|
||||||
|
b = fabs(b);
|
||||||
|
return d / (a > b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
ostringstream os;
|
||||||
|
|
||||||
|
for(int i=0; i<40; i++)
|
||||||
|
{
|
||||||
|
os << i << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
costream cout;
|
||||||
|
|
||||||
|
istringstream is(os.str());
|
||||||
|
|
||||||
|
int j = 0, k = 47;
|
||||||
|
#if 1
|
||||||
|
|
||||||
|
while (is >> k)
|
||||||
|
{
|
||||||
|
assert(k == j++);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(j == 40);
|
||||||
|
#endif
|
||||||
|
os.str(string());
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
cout << "[" << os.str() << "]" << endl;
|
||||||
|
os << "HELLO";
|
||||||
|
cout << "[" << os.str() << "]" << endl;
|
||||||
|
#endif
|
||||||
|
#if 1
|
||||||
|
|
||||||
|
float f = 1.0, g = 1.0;
|
||||||
|
|
||||||
|
for(int i=0; i<10; i++)
|
||||||
|
{
|
||||||
|
os << f << " " << g << endl;
|
||||||
|
// cout << os.str();
|
||||||
|
|
||||||
|
f *= 5.1;
|
||||||
|
g *= 0.12;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
is.str(os.str());
|
||||||
|
|
||||||
|
f = 1.0, g = 1.0;
|
||||||
|
|
||||||
|
float fr, gr;
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
while (is >> fr >> gr)
|
||||||
|
{
|
||||||
|
// cout << f << " " << fr << ", " << g << " " << gr << ", " << fdist(fr, f) << endl;
|
||||||
|
|
||||||
|
assert(fdist(fr, f) < 1.0e-5);
|
||||||
|
assert(fdist(gr, g) < 1.0e-5);
|
||||||
|
|
||||||
|
f *= 5.1;
|
||||||
|
g *= 0.12;
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(j == 10);
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -6,7 +6,7 @@ ios::ios(void)
|
||||||
: mFlags(0), mState(0), mWidth(0), mPrecision(6), mFill(' ')
|
: mFlags(0), mState(0), mWidth(0), mPrecision(6), mFill(' ')
|
||||||
{}
|
{}
|
||||||
|
|
||||||
ios::~ios(void)
|
inline ios::~ios(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ ostream & operator<<(ostream & os, const iosetfill & s)
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
ostream::ostream(void)
|
inline ostream::ostream(void)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
@ -545,7 +545,7 @@ ostream & ostream::operator<<(const string & s)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ostream & ostream::operator<<(manip m)
|
inline ostream & ostream::operator<<(manip m)
|
||||||
{
|
{
|
||||||
return m(*this);
|
return m(*this);
|
||||||
}
|
}
|
||||||
|
@ -711,6 +711,8 @@ unsigned istream::getnum(void)
|
||||||
else if (ch == '+')
|
else if (ch == '+')
|
||||||
ch = get();
|
ch = get();
|
||||||
|
|
||||||
|
bool digits = false;
|
||||||
|
|
||||||
if (ch == '0')
|
if (ch == '0')
|
||||||
{
|
{
|
||||||
if (bflags == 0)
|
if (bflags == 0)
|
||||||
|
@ -722,10 +724,13 @@ unsigned istream::getnum(void)
|
||||||
base = 16;
|
base = 16;
|
||||||
ch = get();
|
ch = get();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
digits = true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
digits = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool digits = false;
|
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
if (ch >= '0' && ch <= '9')
|
if (ch >= '0' && ch <= '9')
|
||||||
|
|
|
@ -16,9 +16,9 @@ void ostringstream::bput(char ch)
|
||||||
{
|
{
|
||||||
if (!mBuffer)
|
if (!mBuffer)
|
||||||
{
|
{
|
||||||
mBSize = 16;
|
mBSize = 15;
|
||||||
mBFill = 0;
|
mBFill = 0;
|
||||||
mBuffer = malloc(16);
|
mBuffer = malloc(15);
|
||||||
}
|
}
|
||||||
else if (mBFill == mBSize)
|
else if (mBFill == mBSize)
|
||||||
{
|
{
|
||||||
|
@ -63,6 +63,7 @@ string istringstream::str(void) const
|
||||||
|
|
||||||
void istringstream::str(const string & str)
|
void istringstream::str(const string & str)
|
||||||
{
|
{
|
||||||
|
mState = goodbit;
|
||||||
mString = str;
|
mString = str;
|
||||||
mSPos = 0;
|
mSPos = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3271,7 +3271,7 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
|
||||||
cins.mRegisterFinal = ins->mSrc[1].mFinal;
|
cins.mRegisterFinal = ins->mSrc[1].mFinal;
|
||||||
mIns.Push(cins);
|
mIns.Push(cins);
|
||||||
}
|
}
|
||||||
else if (ins->mSrc[0].mType == IT_INT8)
|
else if (ins->mSrc[0].mType == IT_INT8 || ins->mSrc[0].mType == IT_BOOL)
|
||||||
{
|
{
|
||||||
if (ins->mSrc[1].mTemp < 0)
|
if (ins->mSrc[1].mTemp < 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,7 +28,10 @@ static bool IsIntegerType(InterType type)
|
||||||
|
|
||||||
IntegerValueRange::IntegerValueRange(void)
|
IntegerValueRange::IntegerValueRange(void)
|
||||||
: mMinState(S_UNKNOWN), mMaxState(S_UNKNOWN)
|
: mMinState(S_UNKNOWN), mMaxState(S_UNKNOWN)
|
||||||
{}
|
{
|
||||||
|
mMinExpanded = 0;
|
||||||
|
mMaxExpanded = 0;
|
||||||
|
}
|
||||||
|
|
||||||
IntegerValueRange::~IntegerValueRange(void)
|
IntegerValueRange::~IntegerValueRange(void)
|
||||||
{}
|
{}
|
||||||
|
@ -37,6 +40,8 @@ void IntegerValueRange::Reset(void)
|
||||||
{
|
{
|
||||||
mMinState = S_UNKNOWN;
|
mMinState = S_UNKNOWN;
|
||||||
mMaxState = S_UNKNOWN;
|
mMaxState = S_UNKNOWN;
|
||||||
|
mMinExpanded = 0;
|
||||||
|
mMaxExpanded = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -126,6 +131,34 @@ void IntegerValueRange::SetLimit(int64 minValue, int64 maxValue)
|
||||||
mMaxValue = maxValue;
|
mMaxValue = maxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IntegerValueRange::Expand(const IntegerValueRange& range)
|
||||||
|
{
|
||||||
|
if (range.mMinState == S_BOUND && mMinState == S_BOUND && range.mMinValue < mMinValue)
|
||||||
|
{
|
||||||
|
mMinValue = range.mMinValue;
|
||||||
|
mMinExpanded++;
|
||||||
|
if (mMinExpanded >= 32)
|
||||||
|
mMinState = S_UNBOUND;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mMinState = range.mMinState;
|
||||||
|
mMinValue = range.mMinValue;
|
||||||
|
}
|
||||||
|
if (range.mMaxState == S_BOUND && mMaxState == S_BOUND && range.mMaxValue > mMaxValue)
|
||||||
|
{
|
||||||
|
mMaxValue = range.mMaxValue;
|
||||||
|
mMaxExpanded++;
|
||||||
|
if (mMaxExpanded >= 32)
|
||||||
|
mMaxState = S_UNBOUND;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mMaxState = range.mMaxState;
|
||||||
|
mMaxValue = range.mMaxValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool IntegerValueRange::Merge(const IntegerValueRange& range, bool head, bool initial)
|
bool IntegerValueRange::Merge(const IntegerValueRange& range, bool head, bool initial)
|
||||||
{
|
{
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
@ -4211,7 +4244,7 @@ void InterOperand::Disassemble(FILE* file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterInstruction::Disassemble(FILE* file)
|
void InterInstruction::Disassemble(FILE* file, InterCodeProcedure* proc)
|
||||||
{
|
{
|
||||||
if (this->mCode != IC_NONE)
|
if (this->mCode != IC_NONE)
|
||||||
{
|
{
|
||||||
|
@ -4353,7 +4386,19 @@ void InterInstruction::Disassemble(FILE* file)
|
||||||
{
|
{
|
||||||
if (mDst.mType == IT_POINTER)
|
if (mDst.mType == IT_POINTER)
|
||||||
{
|
{
|
||||||
fprintf(file, "C%c%d(%d:%d)", memchars[mConst.mMemory], mConst.mOperandSize, mConst.mVarIndex, int(mConst.mIntConst));
|
const char* vname = "";
|
||||||
|
|
||||||
|
if (mConst.mMemory == IM_LOCAL)
|
||||||
|
{
|
||||||
|
if (!proc->mLocalVars[mConst.mVarIndex])
|
||||||
|
vname = "null";
|
||||||
|
else if (!proc->mLocalVars[mConst.mVarIndex]->mIdent)
|
||||||
|
vname = "";
|
||||||
|
else
|
||||||
|
vname = proc->mLocalVars[mConst.mVarIndex]->mIdent->mString;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(file, "C%c%d(%d:%d '%s')", memchars[mConst.mMemory], mConst.mOperandSize, mConst.mVarIndex, int(mConst.mIntConst), vname);
|
||||||
}
|
}
|
||||||
else if (mDst.mType == IT_FLOAT)
|
else if (mDst.mType == IT_FLOAT)
|
||||||
fprintf(file, "CF:%f", mConst.mFloatConst);
|
fprintf(file, "CF:%f", mConst.mFloatConst);
|
||||||
|
@ -4610,6 +4655,27 @@ void InterCodeBasicBlock::GenerateTraces(bool expand, bool compact)
|
||||||
if (mFalseJump)
|
if (mFalseJump)
|
||||||
mFalseJump->mNumEntries++;
|
mFalseJump->mNumEntries++;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
compact &&
|
||||||
|
mFalseJump &&
|
||||||
|
mInstructions.Size() > 0 &&
|
||||||
|
mInstructions.Last()->mCode == IC_BRANCH &&
|
||||||
|
mInstructions.Last()->mSrc[0].mTemp < 0)
|
||||||
|
{
|
||||||
|
int ns = mInstructions.Size();
|
||||||
|
|
||||||
|
if (mInstructions.Last()->mSrc[0].mIntConst)
|
||||||
|
mFalseJump->mNumEntries--;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mTrueJump->mNumEntries--;
|
||||||
|
mTrueJump = mFalseJump;
|
||||||
|
}
|
||||||
|
|
||||||
|
mFalseJump = nullptr;
|
||||||
|
mInstructions[ns - 1]->mCode = IC_JUMP;
|
||||||
|
mInstructions[ns - 1]->mNumOperands = 0;
|
||||||
|
}
|
||||||
else if (mTrueJump && !mFalseJump && ((expand && mTrueJump->mInstructions.Size() < 10 && mTrueJump->mInstructions.Size() > 1 && !mLoopHead) || mTrueJump->mNumEntries == 1) && !mTrueJump->mLoopHead && !IsInfiniteLoop(mTrueJump, mTrueJump))
|
else if (mTrueJump && !mFalseJump && ((expand && mTrueJump->mInstructions.Size() < 10 && mTrueJump->mInstructions.Size() > 1 && !mLoopHead) || mTrueJump->mNumEntries == 1) && !mTrueJump->mLoopHead && !IsInfiniteLoop(mTrueJump, mTrueJump))
|
||||||
{
|
{
|
||||||
mTrueJump->mNumEntries--;
|
mTrueJump->mNumEntries--;
|
||||||
|
@ -5462,6 +5528,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
|
||||||
if (ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT)
|
if (ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT)
|
||||||
{
|
{
|
||||||
ins->mSrc[0].mIntConst = tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst;
|
ins->mSrc[0].mIntConst = tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst;
|
||||||
|
ins->mSrc[0].mMemory = tvalue[ins->mSrc[0].mTemp]->mConst.mMemory;
|
||||||
ins->mSrc[0].mTemp = -1;
|
ins->mSrc[0].mTemp = -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -5900,7 +5967,11 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void)
|
||||||
constFalse = true;
|
constFalse = true;
|
||||||
break;
|
break;
|
||||||
case IA_CMPLU:
|
case IA_CMPLU:
|
||||||
if (cins->mSrc[1].IsUnsigned() && cins->mSrc[0].IsUnsigned())
|
if (cins->mSrc[0].mTemp < 0 && cins->mSrc[0].mIntConst == 0)
|
||||||
|
{
|
||||||
|
constFalse = true;
|
||||||
|
}
|
||||||
|
else if (cins->mSrc[1].IsUnsigned() && cins->mSrc[0].IsUnsigned())
|
||||||
{
|
{
|
||||||
if (cins->mSrc[1].mRange.mMaxValue < cins->mSrc[0].mRange.mMinValue)
|
if (cins->mSrc[1].mRange.mMaxValue < cins->mSrc[0].mRange.mMinValue)
|
||||||
constTrue = true;
|
constTrue = true;
|
||||||
|
@ -5930,7 +6001,11 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void)
|
||||||
constFalse = true;
|
constFalse = true;
|
||||||
break;
|
break;
|
||||||
case IA_CMPGU:
|
case IA_CMPGU:
|
||||||
if (cins->mSrc[1].IsUnsigned() && cins->mSrc[0].IsUnsigned())
|
if (cins->mSrc[1].mTemp < 0 && cins->mSrc[1].mIntConst == 0)
|
||||||
|
{
|
||||||
|
constFalse = true;
|
||||||
|
}
|
||||||
|
else if (cins->mSrc[1].IsUnsigned() && cins->mSrc[0].IsUnsigned())
|
||||||
{
|
{
|
||||||
if (cins->mSrc[1].mRange.mMinValue > cins->mSrc[0].mRange.mMaxValue)
|
if (cins->mSrc[1].mRange.mMinValue > cins->mSrc[0].mRange.mMaxValue)
|
||||||
constTrue = true;
|
constTrue = true;
|
||||||
|
@ -6187,8 +6262,15 @@ bool InterCodeBasicBlock::BuildGlobalIntegerRangeSets(bool initial, const Growin
|
||||||
|
|
||||||
if (changed)
|
if (changed)
|
||||||
{
|
{
|
||||||
mEntryValueRange = mLocalValueRange;
|
for (int i = 0; i < mLocalValueRange.Size(); i++)
|
||||||
mEntryParamValueRange = mLocalParamValueRange;
|
mEntryValueRange[i].Expand(mLocalValueRange[i]);
|
||||||
|
for (int i = 0; i < mLocalParamValueRange.Size(); i++)
|
||||||
|
mEntryParamValueRange[i].Expand(mLocalParamValueRange[i]);
|
||||||
|
mLocalValueRange = mEntryValueRange;
|
||||||
|
mLocalParamValueRange = mEntryParamValueRange;
|
||||||
|
|
||||||
|
// mEntryValueRange = mLocalValueRange;
|
||||||
|
// mEntryParamValueRange = mLocalParamValueRange;
|
||||||
|
|
||||||
UpdateLocalIntegerRangeSets(localVars, paramVars);
|
UpdateLocalIntegerRangeSets(localVars, paramVars);
|
||||||
|
|
||||||
|
@ -15267,7 +15349,11 @@ void InterCodeBasicBlock::Disassemble(FILE* file, bool dumpSets)
|
||||||
|
|
||||||
const char* s = mLoopHead ? "Head" : "";
|
const char* s = mLoopHead ? "Head" : "";
|
||||||
|
|
||||||
fprintf(file, "L%d: <= D%d: (%d) %s P%d\n", mIndex, (mDominator ? mDominator->mIndex : -1), mNumEntries, s, (mLoopPrefix ? mLoopPrefix->mIndex : -1));
|
fprintf(file, "L%d: <= D%d: (%d) %s P%d", mIndex, (mDominator ? mDominator->mIndex : -1), mNumEntries, s, (mLoopPrefix ? mLoopPrefix->mIndex : -1));
|
||||||
|
if (mInstructions.Size())
|
||||||
|
fprintf(file, "%s\n", mInstructions[0]->mLocation.mFileName);
|
||||||
|
else
|
||||||
|
fprintf(file, "\n");
|
||||||
|
|
||||||
if (dumpSets)
|
if (dumpSets)
|
||||||
{
|
{
|
||||||
|
@ -15295,8 +15381,8 @@ void InterCodeBasicBlock::Disassemble(FILE* file, bool dumpSets)
|
||||||
{
|
{
|
||||||
if (mInstructions[i]->mCode != IC_NONE)
|
if (mInstructions[i]->mCode != IC_NONE)
|
||||||
{
|
{
|
||||||
fprintf(file, "%04x\t", i);
|
fprintf(file, "%04x (%4d)\t", i, mInstructions[i]->mLocation.mLine);
|
||||||
mInstructions[i]->Disassemble(file);
|
mInstructions[i]->Disassemble(file, mProc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16176,7 +16262,7 @@ void InterCodeProcedure::Close(void)
|
||||||
{
|
{
|
||||||
GrowingTypeArray tstack(IT_NONE);
|
GrowingTypeArray tstack(IT_NONE);
|
||||||
|
|
||||||
CheckFunc = !strcmp(mIdent->mString, "string::find");
|
CheckFunc = !strcmp(mIdent->mString, "main");
|
||||||
|
|
||||||
mEntryBlock = mBlocks[0];
|
mEntryBlock = mBlocks[0];
|
||||||
|
|
||||||
|
@ -16274,9 +16360,11 @@ void InterCodeProcedure::Close(void)
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->PerformMachineSpecificValueUsageCheck(mValueForwardingTable, tvalidSet, mModule->mGlobalVars, fsingleSet);
|
mEntryBlock->PerformMachineSpecificValueUsageCheck(mValueForwardingTable, tvalidSet, mModule->mGlobalVars, fsingleSet);
|
||||||
|
|
||||||
|
DisassembleDebug("machine value forwarding");
|
||||||
|
|
||||||
GlobalConstantPropagation();
|
GlobalConstantPropagation();
|
||||||
|
|
||||||
DisassembleDebug("machine value forwarding");
|
DisassembleDebug("Global Constant Propagation");
|
||||||
|
|
||||||
//
|
//
|
||||||
// Now remove needless temporary moves, that appear due to
|
// Now remove needless temporary moves, that appear due to
|
||||||
|
|
|
@ -150,6 +150,7 @@ public:
|
||||||
void Reset(void);
|
void Reset(void);
|
||||||
|
|
||||||
int64 mMinValue, mMaxValue;
|
int64 mMinValue, mMaxValue;
|
||||||
|
int mMinExpanded, mMaxExpanded;
|
||||||
|
|
||||||
enum State
|
enum State
|
||||||
{
|
{
|
||||||
|
@ -161,6 +162,7 @@ public:
|
||||||
|
|
||||||
bool Same(const IntegerValueRange& range) const;
|
bool Same(const IntegerValueRange& range) const;
|
||||||
bool Merge(const IntegerValueRange& range, bool head, bool initial);
|
bool Merge(const IntegerValueRange& range, bool head, bool initial);
|
||||||
|
void Expand(const IntegerValueRange& range);
|
||||||
|
|
||||||
void Limit(const IntegerValueRange& range);
|
void Limit(const IntegerValueRange& range);
|
||||||
void SetLimit(int64 minValue, int64 maxValue);
|
void SetLimit(int64 minValue, int64 maxValue);
|
||||||
|
@ -341,7 +343,7 @@ public:
|
||||||
bool ConstantFolding(void);
|
bool ConstantFolding(void);
|
||||||
bool ConstantFoldingRelationRange(void);
|
bool ConstantFoldingRelationRange(void);
|
||||||
|
|
||||||
void Disassemble(FILE* file);
|
void Disassemble(FILE* file, InterCodeProcedure * proc);
|
||||||
};
|
};
|
||||||
|
|
||||||
class InterCodeBasicBlock
|
class InterCodeBasicBlock
|
||||||
|
|
|
@ -321,7 +321,13 @@ void InterCodeGenerator::InitLocalVariable(InterCodeProcedure* proc, Declaration
|
||||||
proc->mLocalVars[index]->mIdent = dec->mIdent;
|
proc->mLocalVars[index]->mIdent = dec->mIdent;
|
||||||
proc->mLocalVars[index]->mDeclaration = dec;
|
proc->mLocalVars[index]->mDeclaration = dec;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(proc->mLocalVars[index]->mIdent == dec->mIdent);
|
||||||
|
assert(proc->mLocalVars[index]->mDeclaration == dec);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const Ident* StructIdent(const Ident* base, const Ident* item)
|
static const Ident* StructIdent(const Ident* base, const Ident* item)
|
||||||
{
|
{
|
||||||
if (base)
|
if (base)
|
||||||
|
@ -1063,7 +1069,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vl = TranslateExpression(ftype, proc, block, fexp, destack, BranchTarget(), BranchTarget(), &nmapper);
|
DestructStack* idestack = nullptr;
|
||||||
|
|
||||||
|
vl = TranslateExpression(ftype, proc, block, fexp, idestack, BranchTarget(), BranchTarget(), &nmapper);
|
||||||
|
|
||||||
InterInstruction* jins = new InterInstruction(exp->mLocation, IC_JUMP);
|
InterInstruction* jins = new InterInstruction(exp->mLocation, IC_JUMP);
|
||||||
block->Append(jins);
|
block->Append(jins);
|
||||||
|
@ -1071,7 +1079,11 @@ 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);
|
// Unwind inner destruct stack
|
||||||
|
UnwindDestructStack(ftype, proc, block, idestack, nullptr, &nmapper);
|
||||||
|
|
||||||
|
// Uwind parameter passing stack
|
||||||
|
UnwindDestructStack(ftype, proc, block, destack, nullptr, inlineMapper);
|
||||||
|
|
||||||
if (rdec)
|
if (rdec)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1706,6 +1706,7 @@ void Parser::BuildMemberConstructor(Declaration* pthis, Declaration* cfunc)
|
||||||
void Parser::AddDefaultConstructors(Declaration* pthis)
|
void Parser::AddDefaultConstructors(Declaration* pthis)
|
||||||
{
|
{
|
||||||
bool simpleDestructor = true, simpleAssignment = true, simpleConstructor = true, simpleCopy = true;
|
bool simpleDestructor = true, simpleAssignment = true, simpleConstructor = true, simpleCopy = true;
|
||||||
|
bool inlineDestructor = true;
|
||||||
bool inlineConstructor = true;
|
bool inlineConstructor = true;
|
||||||
|
|
||||||
char dname[100];
|
char dname[100];
|
||||||
|
@ -1750,7 +1751,11 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
|
||||||
while (bcdec)
|
while (bcdec)
|
||||||
{
|
{
|
||||||
if (bcdec->mBase->mDestructor)
|
if (bcdec->mBase->mDestructor)
|
||||||
|
{
|
||||||
|
if (!(bcdec->mBase->mDestructor->mBase->mFlags & DTF_REQUEST_INLINE))
|
||||||
|
inlineConstructor = false;
|
||||||
simpleDestructor = false;
|
simpleDestructor = false;
|
||||||
|
}
|
||||||
if (bcdec->mBase->mDefaultConstructor)
|
if (bcdec->mBase->mDefaultConstructor)
|
||||||
{
|
{
|
||||||
simpleConstructor = false;
|
simpleConstructor = false;
|
||||||
|
@ -1781,7 +1786,11 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
|
||||||
if (bdec->mType == DT_TYPE_STRUCT)
|
if (bdec->mType == DT_TYPE_STRUCT)
|
||||||
{
|
{
|
||||||
if (bdec->mDestructor)
|
if (bdec->mDestructor)
|
||||||
|
{
|
||||||
simpleDestructor = false;
|
simpleDestructor = false;
|
||||||
|
if (!(bdec->mDestructor->mBase->mFlags & DTF_REQUEST_INLINE))
|
||||||
|
inlineDestructor = false;
|
||||||
|
}
|
||||||
if (bdec->mDefaultConstructor)
|
if (bdec->mDefaultConstructor)
|
||||||
{
|
{
|
||||||
simpleConstructor = false;
|
simpleConstructor = false;
|
||||||
|
@ -1813,6 +1822,8 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
|
||||||
cdec->mBase = ctdec;
|
cdec->mBase = ctdec;
|
||||||
|
|
||||||
cdec->mFlags |= cdec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE);
|
cdec->mFlags |= cdec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE);
|
||||||
|
if (inlineDestructor)
|
||||||
|
cdec->mFlags |= DTF_REQUEST_INLINE;
|
||||||
|
|
||||||
cdec->mSection = mCodeSection;
|
cdec->mSection = mCodeSection;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue