Add bounded integer class
This commit is contained in:
parent
8e46ae95ec
commit
e37de95079
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef OPP_BOUNDINT_H
|
||||||
|
#define OPP_BOUNDINT_H
|
||||||
|
|
||||||
|
namespace opp {
|
||||||
|
|
||||||
|
template<int tmin, int tmax>
|
||||||
|
constexpr auto boundinttype(void)
|
||||||
|
{
|
||||||
|
if constexpr (tmin >= 0 && tmax <= 255)
|
||||||
|
return (char)0;
|
||||||
|
else if constexpr (tmin >= -128 && tmax <= 127)
|
||||||
|
return (signed char)0;
|
||||||
|
else
|
||||||
|
return (int)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int tmin, int tmax>
|
||||||
|
class boundint
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
decltype(boundinttype<tmin, tmax>()) v;
|
||||||
|
public:
|
||||||
|
boundint(int i)
|
||||||
|
: v(i)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator=(int k)
|
||||||
|
{
|
||||||
|
__assume(k >= tmin && k <= tmax);
|
||||||
|
v = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator int() const
|
||||||
|
{
|
||||||
|
int k = v;
|
||||||
|
__assume(k >= tmin && k <= tmax);
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -754,6 +754,9 @@ bool ConstexprInterpreter::AddParam(int& pos, Expression* pex, Declaration* dec)
|
||||||
|
|
||||||
Expression* ConstexprInterpreter::EvalCall(Expression* exp)
|
Expression* ConstexprInterpreter::EvalCall(Expression* exp)
|
||||||
{
|
{
|
||||||
|
if (!exp->mLeft->mDecValue || !exp->mLeft->mDecValue->mValue)
|
||||||
|
return exp;
|
||||||
|
|
||||||
mProcType = exp->mLeft->mDecType;
|
mProcType = exp->mLeft->mDecType;
|
||||||
|
|
||||||
Expression* pex = exp->mRight;
|
Expression* pex = exp->mRight;
|
||||||
|
|
|
@ -491,6 +491,47 @@ Expression* Expression::LogicInvertExpression(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Expression* Expression::ToAlternateThis(Declaration* pthis, Declaration* nthis)
|
||||||
|
{
|
||||||
|
Expression* left = mLeft ? mLeft->ToAlternateThis(pthis, nthis) : nullptr;
|
||||||
|
Expression* right = mRight ? mRight->ToAlternateThis(pthis, nthis) : nullptr;
|
||||||
|
Declaration* decType = mDecType, * decValue = mDecValue;
|
||||||
|
|
||||||
|
if (decType == pthis->mBase)
|
||||||
|
decType = nthis->mBase;
|
||||||
|
else if (decType == pthis->mBase->mBase)
|
||||||
|
decType = nthis->mBase->mBase;
|
||||||
|
if (decValue == pthis)
|
||||||
|
decValue = nthis;
|
||||||
|
|
||||||
|
if (mType == EX_QUALIFY && mLeft->mDecType != left->mDecType)
|
||||||
|
{
|
||||||
|
Declaration* pe = mLeft->mDecType->mParams, * ne = left->mDecType->mParams;
|
||||||
|
while (pe && ne && pe != mDecValue)
|
||||||
|
{
|
||||||
|
pe = pe->mNext;
|
||||||
|
ne = ne->mNext;
|
||||||
|
}
|
||||||
|
decValue = ne;
|
||||||
|
decType = ne->mBase;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left == mLeft && right == mRight && decType == mDecType && decValue == mDecValue)
|
||||||
|
return this;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Expression* nexp = new Expression(mLocation, mType);
|
||||||
|
nexp->mLeft = left;
|
||||||
|
nexp->mRight = right;
|
||||||
|
nexp->mDecType = decType;
|
||||||
|
nexp->mDecValue = decValue;
|
||||||
|
nexp->mToken = mToken;
|
||||||
|
nexp->mConst = mConst;
|
||||||
|
|
||||||
|
return nexp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Expression* Expression::ConstantDereference(Errors* errors, LinkerSection* dataSection)
|
Expression* Expression::ConstantDereference(Errors* errors, LinkerSection* dataSection)
|
||||||
{
|
{
|
||||||
if (mType == EX_VARIABLE)
|
if (mType == EX_VARIABLE)
|
||||||
|
@ -1034,6 +1075,26 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (mType == EX_LOGICAL_AND && mLeft->mType == EX_CONSTANT)
|
||||||
|
{
|
||||||
|
if (mLeft->mDecValue->mType == DT_CONST_INTEGER)
|
||||||
|
{
|
||||||
|
if (mLeft->mDecValue->mInteger == 0)
|
||||||
|
return mLeft;
|
||||||
|
else
|
||||||
|
return mRight->ConstantFold(errors, dataSection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mType == EX_LOGICAL_OR && mLeft->mType == EX_CONSTANT)
|
||||||
|
{
|
||||||
|
if (mLeft->mDecValue->mType == DT_CONST_INTEGER)
|
||||||
|
{
|
||||||
|
if (mLeft->mDecValue->mInteger != 0)
|
||||||
|
return mLeft;
|
||||||
|
else
|
||||||
|
return mRight->ConstantFold(errors, dataSection);
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (mType == EX_CONDITIONAL && mLeft->mType == EX_CONSTANT)
|
else if (mType == EX_CONDITIONAL && mLeft->mType == EX_CONSTANT)
|
||||||
{
|
{
|
||||||
if (mLeft->mDecValue->mType == DT_CONST_INTEGER)
|
if (mLeft->mDecValue->mType == DT_CONST_INTEGER)
|
||||||
|
@ -2058,6 +2119,7 @@ Declaration* Declaration::Clone(void)
|
||||||
ndec->mMaxValue = mMaxValue;
|
ndec->mMaxValue = mMaxValue;
|
||||||
ndec->mCompilerOptions = mCompilerOptions;
|
ndec->mCompilerOptions = mCompilerOptions;
|
||||||
ndec->mParser = mParser;
|
ndec->mParser = mParser;
|
||||||
|
ndec->mNumVars = mNumVars;
|
||||||
|
|
||||||
return ndec;
|
return ndec;
|
||||||
}
|
}
|
||||||
|
@ -2136,6 +2198,23 @@ Declaration* Declaration::ToStriped(int stripe)
|
||||||
prev = pnec;
|
prev = pnec;
|
||||||
p = p->mNext;
|
p = p->mNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Declaration* pndec = ndec->BuildPointer(mLocation);
|
||||||
|
|
||||||
|
mScope->Iterate([=](const Ident* ident, Declaration* vdec) {
|
||||||
|
if (vdec->mType == DT_CONST_FUNCTION)
|
||||||
|
{
|
||||||
|
ndec->mScope->Insert(ident, vdec->ToAlternateThis(pndec));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ndec->mDestructor = mDestructor ? mDestructor->ToAlternateThis(pndec) : nullptr;
|
||||||
|
ndec->mDefaultConstructor = mDefaultConstructor ? mDefaultConstructor->ToAlternateThis(pndec) : nullptr;
|
||||||
|
ndec->mCopyConstructor = mCopyConstructor ? mCopyConstructor->ToAlternateThis(pndec) : nullptr;
|
||||||
|
ndec->mMoveConstructor = mMoveConstructor ? mMoveConstructor->ToAlternateThis(pndec) : nullptr;
|
||||||
|
ndec->mVectorConstructor = mVectorConstructor ? mVectorConstructor->ToAlternateThis(pndec, 2) : nullptr;
|
||||||
|
ndec->mVectorDestructor = mVectorDestructor ? mVectorDestructor->ToAlternateThis(pndec, 2) : nullptr;
|
||||||
|
ndec->mVectorCopyConstructor = mVectorCopyConstructor ? mVectorCopyConstructor->ToAlternateThis(pndec, 2) : nullptr;
|
||||||
}
|
}
|
||||||
else if (mType == DT_TYPE_FUNCTION)
|
else if (mType == DT_TYPE_FUNCTION)
|
||||||
{
|
{
|
||||||
|
@ -2244,6 +2323,34 @@ Declaration* Declaration::ToConstType(void)
|
||||||
return mConst;
|
return mConst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Declaration* Declaration::ToAlternateThis(Declaration* pthis, int nthis)
|
||||||
|
{
|
||||||
|
Declaration* ndec = this->Clone();
|
||||||
|
|
||||||
|
if (mType == DT_CONST_FUNCTION)
|
||||||
|
{
|
||||||
|
ndec->mBase = mBase->ToAlternateThis(pthis, nthis);
|
||||||
|
if (mValue)
|
||||||
|
ndec->mValue = mValue->ToAlternateThis(mBase->mParams, ndec->mBase->mParams);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Declaration* nparam = ndec->mParams->Clone();
|
||||||
|
nparam->mBase = pthis;
|
||||||
|
if (nthis == 2)
|
||||||
|
{
|
||||||
|
Declaration* nparam2 = ndec->mParams->mNext->Clone();
|
||||||
|
nparam2->mBase = pthis;
|
||||||
|
nparam->mNext = nparam2;
|
||||||
|
nparam2->mNext = ndec->mParams->mNext->mNext;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nparam->mNext = ndec->mParams->mNext;
|
||||||
|
ndec->mParams = nparam;
|
||||||
|
}
|
||||||
|
return ndec;
|
||||||
|
}
|
||||||
|
|
||||||
Declaration* Declaration::ToMutableType(void)
|
Declaration* Declaration::ToMutableType(void)
|
||||||
{
|
{
|
||||||
if (!(mFlags & DTF_CONST))
|
if (!(mFlags & DTF_CONST))
|
||||||
|
|
|
@ -264,6 +264,7 @@ public:
|
||||||
Expression* ConstantDereference(Errors* errors, LinkerSection* dataSection);
|
Expression* ConstantDereference(Errors* errors, LinkerSection* dataSection);
|
||||||
bool HasSideEffects(void) const;
|
bool HasSideEffects(void) const;
|
||||||
Expression* ListAppend(Expression* lexp);
|
Expression* ListAppend(Expression* lexp);
|
||||||
|
Expression* ToAlternateThis(Declaration* pthis, Declaration* nthis);
|
||||||
|
|
||||||
bool IsSame(const Expression* exp) const;
|
bool IsSame(const Expression* exp) const;
|
||||||
bool IsRValue(void) const;
|
bool IsRValue(void) const;
|
||||||
|
@ -271,6 +272,7 @@ public:
|
||||||
bool IsConstRef(void) const;
|
bool IsConstRef(void) const;
|
||||||
bool IsVolatile(void) const;
|
bool IsVolatile(void) const;
|
||||||
|
|
||||||
|
|
||||||
void Dump(int ident) const;
|
void Dump(int ident) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -335,6 +337,7 @@ public:
|
||||||
Declaration* ToConstType(void);
|
Declaration* ToConstType(void);
|
||||||
Declaration* ToMutableType(void);
|
Declaration* ToMutableType(void);
|
||||||
Declaration* ToVolatileType(void);
|
Declaration* ToVolatileType(void);
|
||||||
|
Declaration* ToAlternateThis(Declaration* pthis, int nthis = 1);
|
||||||
|
|
||||||
Declaration* ToStriped(int stripe);
|
Declaration* ToStriped(int stripe);
|
||||||
Declaration* ToStriped(Errors* errors);
|
Declaration* ToStriped(Errors* errors);
|
||||||
|
|
|
@ -46583,6 +46583,32 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerIterate4(int i, int pass)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_STA &&
|
||||||
|
mIns[i + 1].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_LDX, mIns[i + 1].mMode) &&
|
||||||
|
mIns[i + 2].mType == ASMIT_STA && HasAsmInstructionMode(ASMIT_STX, mIns[i + 2].mMode) &&
|
||||||
|
mIns[i + 3].mType == ASMIT_LDX && mIns[i + 3].SameEffectiveAddress(mIns[i + 0]))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mLive |= LIVE_CPU_REG_A;
|
||||||
|
mIns[i + 1].mType = ASMIT_LDX; mIns[i + 1].mLive |= LIVE_CPU_REG_X;
|
||||||
|
mIns[i + 2].mType = ASMIT_STX; mIns[i + 2].mLive |= LIVE_CPU_REG_A;
|
||||||
|
mIns[i + 3].mType = ASMIT_TAX; mIns[i + 3].mMode = ASMIM_IMPLIED;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_STA &&
|
||||||
|
mIns[i + 1].mType == ASMIT_LDA && HasAsmInstructionMode(ASMIT_LDY, mIns[i + 1].mMode) &&
|
||||||
|
mIns[i + 2].mType == ASMIT_STA && HasAsmInstructionMode(ASMIT_STY, mIns[i + 2].mMode) &&
|
||||||
|
mIns[i + 3].mType == ASMIT_LDY && mIns[i + 3].SameEffectiveAddress(mIns[i + 0]))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mLive |= LIVE_CPU_REG_A;
|
||||||
|
mIns[i + 1].mType = ASMIT_LDY; mIns[i + 1].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
mIns[i + 2].mType = ASMIT_STY; mIns[i + 2].mLive |= LIVE_CPU_REG_A;
|
||||||
|
mIns[i + 3].mType = ASMIT_TAY; mIns[i + 3].mMode = ASMIM_IMPLIED;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
|
||||||
mIns[i + 1].mType == ASMIT_LDY && mIns[i + 1].mMode == ASMIM_IMMEDIATE &&
|
mIns[i + 1].mType == ASMIT_LDY && mIns[i + 1].mMode == ASMIM_IMMEDIATE &&
|
||||||
|
|
|
@ -869,6 +869,14 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified, Decl
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TK_DECLTYPE:
|
||||||
|
{
|
||||||
|
mScanner->NextToken();
|
||||||
|
Expression* exp = ParseExpression(true);
|
||||||
|
dec = exp->mDecType;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case TK_IDENT:
|
case TK_IDENT:
|
||||||
pident = mScanner->mTokenIdent;
|
pident = mScanner->mTokenIdent;
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
|
@ -5321,7 +5329,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
||||||
|
|
||||||
if (pdec)
|
if (pdec)
|
||||||
{
|
{
|
||||||
if (!ndec->mBase->IsSame(pdec->mBase))
|
if (!ndec->mBase->IsSame(pdec->mBase) && !(ndec->mBase->mBase->mType == DT_TYPE_AUTO && ndec->mBase->IsSameParams(pdec->mBase)))
|
||||||
{
|
{
|
||||||
ndec->mBase->IsSameParams(pdec->mBase);
|
ndec->mBase->IsSameParams(pdec->mBase);
|
||||||
ndec->mBase->IsSame(pdec->mBase);
|
ndec->mBase->IsSame(pdec->mBase);
|
||||||
|
@ -6384,6 +6392,7 @@ Expression* Parser::ParseSimpleExpression(bool lhs, bool tid)
|
||||||
case TK_STATIC:
|
case TK_STATIC:
|
||||||
case TK_AUTO:
|
case TK_AUTO:
|
||||||
case TK_STRIPED:
|
case TK_STRIPED:
|
||||||
|
case TK_DECLTYPE:
|
||||||
exp = ParseDeclarationExpression(nullptr);
|
exp = ParseDeclarationExpression(nullptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -7461,6 +7470,7 @@ Expression* Parser::CoerceExpression(Expression* exp, Declaration* type)
|
||||||
nexp->mLeft->mDecType = fexp->mBase;
|
nexp->mLeft->mDecType = fexp->mBase;
|
||||||
nexp->mLeft->mDecValue = fexp;
|
nexp->mLeft->mDecValue = fexp;
|
||||||
nexp->mRight = aexp;
|
nexp->mRight = aexp;
|
||||||
|
nexp->mDecType = fexp->mBase->mBase;
|
||||||
|
|
||||||
return nexp;
|
return nexp;
|
||||||
}
|
}
|
||||||
|
@ -9349,6 +9359,9 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
|
||||||
Declaration* tdec = exp->mLeft->mDecType;
|
Declaration* tdec = exp->mLeft->mDecType;
|
||||||
while (tdec->mType == DT_TYPE_REFERENCE || tdec->mType == DT_TYPE_RVALUEREF)
|
while (tdec->mType == DT_TYPE_REFERENCE || tdec->mType == DT_TYPE_RVALUEREF)
|
||||||
tdec = tdec->mBase;
|
tdec = tdec->mBase;
|
||||||
|
Declaration* rtdec = exp->mRight->mDecType;
|
||||||
|
while (rtdec->mType == DT_TYPE_REFERENCE || rtdec->mType == DT_TYPE_RVALUEREF)
|
||||||
|
rtdec = rtdec->mBase;
|
||||||
|
|
||||||
if (tdec->mType == DT_TYPE_STRUCT)
|
if (tdec->mType == DT_TYPE_STRUCT)
|
||||||
{
|
{
|
||||||
|
@ -9383,6 +9396,18 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
|
||||||
exp = nexp;
|
exp = nexp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (exp->mType != EX_CALL && !nexp2 && (tdec->mType == DT_TYPE_STRUCT || rtdec->mType == DT_TYPE_STRUCT))
|
||||||
|
{
|
||||||
|
if ((exp->mLeft->mDecType->IsIntegerType() || CanCoerceExpression(exp->mLeft, TheSignedIntTypeDeclaration)) &&
|
||||||
|
(exp->mRight->mDecType->IsIntegerType() || CanCoerceExpression(exp->mRight, TheSignedIntTypeDeclaration)))
|
||||||
|
{
|
||||||
|
exp->mLeft = CoerceExpression(exp->mLeft, TheSignedIntTypeDeclaration);
|
||||||
|
exp->mRight = CoerceExpression(exp->mRight, TheSignedIntTypeDeclaration);
|
||||||
|
if (exp->mType == EX_BINARY)
|
||||||
|
exp->mDecType = TheSignedIntTypeDeclaration;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (exp->mType == EX_PREFIX)
|
else if (exp->mType == EX_PREFIX)
|
||||||
|
@ -9781,6 +9806,12 @@ void Parser::SkipStatement(void)
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (ConsumeTokenIf(TK_IF))
|
||||||
|
{
|
||||||
|
SkipStatement();
|
||||||
|
if (ConsumeTokenIf(TK_ELSE))
|
||||||
|
SkipStatement();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while (!ConsumeTokenIf(TK_SEMICOLON))
|
while (!ConsumeTokenIf(TK_SEMICOLON))
|
||||||
|
@ -12540,6 +12571,7 @@ bool Parser::IsTypeToken(void)
|
||||||
case TK_STATIC:
|
case TK_STATIC:
|
||||||
case TK_AUTO:
|
case TK_AUTO:
|
||||||
case TK_STRIPED:
|
case TK_STRIPED:
|
||||||
|
case TK_DECLTYPE:
|
||||||
return true;
|
return true;
|
||||||
case TK_IDENT:
|
case TK_IDENT:
|
||||||
{
|
{
|
||||||
|
|
|
@ -173,6 +173,7 @@ const char* TokenNames[] =
|
||||||
"'friend'",
|
"'friend'",
|
||||||
"'constexpr'",
|
"'constexpr'",
|
||||||
"'typename'",
|
"'typename'",
|
||||||
|
"'decltype'",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -355,7 +356,7 @@ Scanner::Scanner(Errors* errors, Preprocessor* preprocessor)
|
||||||
mToken = TK_NONE;
|
mToken = TK_NONE;
|
||||||
mUngetToken = TK_NONE;
|
mUngetToken = TK_NONE;
|
||||||
mReplay = nullptr;
|
mReplay = nullptr;
|
||||||
mRecord = mRecordLast = nullptr;
|
mRecord = mRecordLast = mRecordPrev = nullptr;
|
||||||
|
|
||||||
mOnceDict = new MacroDict();
|
mOnceDict = new MacroDict();
|
||||||
|
|
||||||
|
@ -372,13 +373,13 @@ Scanner::~Scanner(void)
|
||||||
|
|
||||||
void Scanner::BeginRecord(void)
|
void Scanner::BeginRecord(void)
|
||||||
{
|
{
|
||||||
mRecord = mRecordLast = new TokenSequence(this);
|
mRecord = mRecordLast = mRecordPrev = new TokenSequence(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
TokenSequence* Scanner::CompleteRecord(void)
|
TokenSequence* Scanner::CompleteRecord(void)
|
||||||
{
|
{
|
||||||
TokenSequence* seq = mRecord;
|
TokenSequence* seq = mRecord;
|
||||||
mRecord = mRecordLast = nullptr;
|
mRecord = mRecordLast = mRecordPrev = nullptr;
|
||||||
return seq;
|
return seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,6 +484,8 @@ void Scanner::UngetToken(Token token)
|
||||||
{
|
{
|
||||||
mUngetToken = mToken;
|
mUngetToken = mToken;
|
||||||
mToken = token;
|
mToken = token;
|
||||||
|
if (mRecord)
|
||||||
|
mRecordLast = mRecordPrev;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scanner::NextToken(void)
|
void Scanner::NextToken(void)
|
||||||
|
@ -491,10 +494,8 @@ void Scanner::NextToken(void)
|
||||||
{
|
{
|
||||||
mToken = mUngetToken;
|
mToken = mUngetToken;
|
||||||
mUngetToken = TK_NONE;
|
mUngetToken = TK_NONE;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else if (mReplay)
|
||||||
if (mReplay)
|
|
||||||
{
|
{
|
||||||
mLocation = mReplay->mLocation;
|
mLocation = mReplay->mLocation;
|
||||||
mToken = mReplay->mToken;
|
mToken = mReplay->mToken;
|
||||||
|
@ -515,6 +516,7 @@ void Scanner::NextToken(void)
|
||||||
|
|
||||||
if (mRecord)
|
if (mRecord)
|
||||||
{
|
{
|
||||||
|
mRecordPrev = mRecordLast;
|
||||||
mRecordLast->mNext = new TokenSequence(this);
|
mRecordLast->mNext = new TokenSequence(this);
|
||||||
mRecordLast = mRecordLast->mNext;
|
mRecordLast = mRecordLast->mNext;
|
||||||
}
|
}
|
||||||
|
@ -1846,6 +1848,8 @@ void Scanner::NextRawToken(void)
|
||||||
mToken = TK_CONSTEXPR;
|
mToken = TK_CONSTEXPR;
|
||||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "typename"))
|
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "typename"))
|
||||||
mToken = TK_TYPENAME;
|
mToken = TK_TYPENAME;
|
||||||
|
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "decltype"))
|
||||||
|
mToken = TK_DECLTYPE;
|
||||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "operator"))
|
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "operator"))
|
||||||
{
|
{
|
||||||
NextRawToken();
|
NextRawToken();
|
||||||
|
|
|
@ -172,6 +172,7 @@ enum Token
|
||||||
TK_FRIEND,
|
TK_FRIEND,
|
||||||
TK_CONSTEXPR,
|
TK_CONSTEXPR,
|
||||||
TK_TYPENAME,
|
TK_TYPENAME,
|
||||||
|
TK_DECLTYPE,
|
||||||
|
|
||||||
NUM_TOKENS
|
NUM_TOKENS
|
||||||
};
|
};
|
||||||
|
@ -315,7 +316,7 @@ protected:
|
||||||
Token mUngetToken;
|
Token mUngetToken;
|
||||||
|
|
||||||
const TokenSequence* mReplay;
|
const TokenSequence* mReplay;
|
||||||
TokenSequence* mRecord, * mRecordLast;
|
TokenSequence* mRecord, * mRecordLast, * mRecordPrev;
|
||||||
|
|
||||||
void StringToken(char terminator, char mode);
|
void StringToken(char terminator, char mode);
|
||||||
void CharToken(char mode);
|
void CharToken(char mode);
|
||||||
|
|
Loading…
Reference in New Issue