Improve C++ compliance
This commit is contained in:
parent
c46870ec10
commit
b7630450f1
|
@ -51,6 +51,8 @@ enum DecType
|
||||||
DT_NAMESPACE,
|
DT_NAMESPACE,
|
||||||
DT_BASECLASS,
|
DT_BASECLASS,
|
||||||
|
|
||||||
|
DT_TEMPLATE,
|
||||||
|
|
||||||
DT_VTABLE
|
DT_VTABLE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -545,6 +545,12 @@ int Emulator::Emulate(int startIP, int trace)
|
||||||
mIP = mMemory[0x101 + mRegS] + 256 * mMemory[0x102 + mRegS] + 1;
|
mIP = mMemory[0x101 + mRegS] + 256 * mMemory[0x102 + mRegS] + 1;
|
||||||
mRegS += 2;
|
mRegS += 2;
|
||||||
}
|
}
|
||||||
|
else if (mIP == 0xff81)
|
||||||
|
{
|
||||||
|
printf("------------------ CLEAR ---------------\n");
|
||||||
|
mIP = mMemory[0x101 + mRegS] + 256 * mMemory[0x102 + mRegS] + 1;
|
||||||
|
mRegS += 2;
|
||||||
|
}
|
||||||
|
|
||||||
uint8 opcode = mMemory[mIP];
|
uint8 opcode = mMemory[mIP];
|
||||||
AsmInsData d = DecInsData[opcode];
|
AsmInsData d = DecInsData[opcode];
|
||||||
|
|
|
@ -80,6 +80,7 @@ enum ErrorID
|
||||||
EERR_INVALID_OPERATOR,
|
EERR_INVALID_OPERATOR,
|
||||||
EERR_MISSING_TEMP,
|
EERR_MISSING_TEMP,
|
||||||
EERR_NON_STATIC_MEMBER,
|
EERR_NON_STATIC_MEMBER,
|
||||||
|
EERR_TEMPLATE_PARAMS,
|
||||||
|
|
||||||
ERRR_STACK_OVERFLOW,
|
ERRR_STACK_OVERFLOW,
|
||||||
ERRR_INVALID_NUMBER,
|
ERRR_INVALID_NUMBER,
|
||||||
|
|
|
@ -13420,6 +13420,18 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
|
||||||
sins->mSrc[0].mFinal = false;
|
sins->mSrc[0].mFinal = false;
|
||||||
assert(nins->mSrc[0].mTemp >= 0);
|
assert(nins->mSrc[0].mTemp >= 0);
|
||||||
|
|
||||||
|
// Propagate all loads to move temps
|
||||||
|
|
||||||
|
for (int t = j + 1; t < mInstructions.Size(); t++)
|
||||||
|
{
|
||||||
|
InterInstruction* ti = mInstructions[t];
|
||||||
|
if (ti->mCode == IC_LOAD && SameMem(ti->mSrc[0], ins->mSrc[0]))
|
||||||
|
{
|
||||||
|
ti->mCode = IC_LOAD_TEMPORARY;
|
||||||
|
ti->mSrc[0].mTemp = ins->mDst.mTemp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Move store behind loop
|
// Move store behind loop
|
||||||
tailBlock->mInstructions.Insert(0, sins);
|
tailBlock->mInstructions.Insert(0, sins);
|
||||||
mInstructions.Remove(j);
|
mInstructions.Remove(j);
|
||||||
|
@ -16724,7 +16736,7 @@ void InterCodeProcedure::Close(void)
|
||||||
{
|
{
|
||||||
GrowingTypeArray tstack(IT_NONE);
|
GrowingTypeArray tstack(IT_NONE);
|
||||||
|
|
||||||
CheckFunc = !strcmp(mIdent->mString, "playSong");
|
CheckFunc = !strcmp(mIdent->mString, "MenuItem::+MenuItem");
|
||||||
|
|
||||||
mEntryBlock = mBlocks[0];
|
mEntryBlock = mBlocks[0];
|
||||||
|
|
||||||
|
@ -16899,6 +16911,8 @@ void InterCodeProcedure::Close(void)
|
||||||
TempForwarding();
|
TempForwarding();
|
||||||
RemoveUnusedInstructions();
|
RemoveUnusedInstructions();
|
||||||
|
|
||||||
|
DisassembleDebug("pre single block loop opt");
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->SingleBlockLoopOptimisation(mParamAliasedSet, mModule->mGlobalVars);
|
mEntryBlock->SingleBlockLoopOptimisation(mParamAliasedSet, mModule->mGlobalVars);
|
||||||
|
|
||||||
|
|
|
@ -4111,6 +4111,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
vr = Dereference(proc, exp, block, vr);
|
vr = Dereference(proc, exp, block, vr);
|
||||||
return CoerceType(proc, exp, block, vr, exp->mDecType);
|
return CoerceType(proc, exp, block, vr, exp->mDecType);
|
||||||
}
|
}
|
||||||
|
else if (exp->mDecType->mType == DT_TYPE_VOID)
|
||||||
|
{
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vr = Dereference(proc, exp, block, vr);
|
vr = Dereference(proc, exp, block, vr);
|
||||||
|
|
|
@ -284,6 +284,15 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
|
||||||
if (dec->mScope->Insert(mdec->mIdent, mdec))
|
if (dec->mScope->Insert(mdec->mIdent, mdec))
|
||||||
mErrors->Error(mdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate struct member declaration", mdec->mIdent);
|
mErrors->Error(mdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate struct member declaration", mdec->mIdent);
|
||||||
|
|
||||||
|
if (dec->mConst)
|
||||||
|
{
|
||||||
|
Declaration* cmdec = mdec->Clone();
|
||||||
|
cmdec->mBase = mdec->mBase->ToConstType();
|
||||||
|
|
||||||
|
dec->mConst->mScope->Insert(cmdec->mIdent, cmdec);
|
||||||
|
dec->mConst->mSize = dec->mSize;
|
||||||
|
}
|
||||||
|
|
||||||
if (mlast)
|
if (mlast)
|
||||||
mlast->mNext = mdec;
|
mlast->mNext = mdec;
|
||||||
else
|
else
|
||||||
|
@ -442,6 +451,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
|
||||||
Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified)
|
Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified)
|
||||||
{
|
{
|
||||||
Declaration* dec = nullptr;
|
Declaration* dec = nullptr;
|
||||||
|
const Ident* pident = nullptr;
|
||||||
|
|
||||||
switch (mScanner->mToken)
|
switch (mScanner->mToken)
|
||||||
{
|
{
|
||||||
|
@ -551,6 +561,7 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TK_IDENT:
|
case TK_IDENT:
|
||||||
|
pident = mScanner->mTokenIdent;
|
||||||
dec = mScope->Lookup(mScanner->mTokenIdent);
|
dec = mScope->Lookup(mScanner->mTokenIdent);
|
||||||
if (dec && dec->mType == DT_CONST_FUNCTION && mScope->mLevel == SLEVEL_CLASS)
|
if (dec && dec->mType == DT_CONST_FUNCTION && mScope->mLevel == SLEVEL_CLASS)
|
||||||
dec = mScope->mParent->Lookup(mScanner->mTokenIdent);
|
dec = mScope->mParent->Lookup(mScanner->mTokenIdent);
|
||||||
|
@ -560,6 +571,7 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified)
|
||||||
{
|
{
|
||||||
if (ExpectToken(TK_IDENT))
|
if (ExpectToken(TK_IDENT))
|
||||||
{
|
{
|
||||||
|
pident = mScanner->mTokenIdent;
|
||||||
dec = dec->mScope->Lookup(mScanner->mTokenIdent);
|
dec = dec->mScope->Lookup(mScanner->mTokenIdent);
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
}
|
}
|
||||||
|
@ -594,15 +606,9 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!dec)
|
else if (!dec)
|
||||||
{
|
mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Identifier not defined", pident);
|
||||||
mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Identifier not defined", mScanner->mTokenIdent);
|
|
||||||
mScanner->NextToken();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
mErrors->Error(mScanner->mLocation, EERR_NOT_A_TYPE, "Identifier is no type", dec->mQualIdent);
|
||||||
mErrors->Error(mScanner->mLocation, EERR_NOT_A_TYPE, "Identifier is no type", mScanner->mTokenIdent);
|
|
||||||
mScanner->NextToken();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TK_ENUM:
|
case TK_ENUM:
|
||||||
|
@ -3424,6 +3430,21 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
||||||
|
|
||||||
if (mScanner->mToken == TK_OPEN_BRACE)
|
if (mScanner->mToken == TK_OPEN_BRACE)
|
||||||
{
|
{
|
||||||
|
//
|
||||||
|
// Take parameter names from new declaration
|
||||||
|
//
|
||||||
|
Declaration* npdec = ctdec->mParams, * ppdec = cdec->mBase->mParams;
|
||||||
|
while (npdec && ppdec)
|
||||||
|
{
|
||||||
|
if (npdec->mIdent)
|
||||||
|
{
|
||||||
|
ppdec->mIdent = npdec->mIdent;
|
||||||
|
ppdec->mQualIdent = npdec->mQualIdent;
|
||||||
|
}
|
||||||
|
npdec = npdec->mNext;
|
||||||
|
ppdec = ppdec->mNext;
|
||||||
|
}
|
||||||
|
|
||||||
if (cdec->mFlags & DTF_DEFINED)
|
if (cdec->mFlags & DTF_DEFINED)
|
||||||
mErrors->Error(cdec->mLocation, EERR_DUPLICATE_DEFINITION, "Function already has a body");
|
mErrors->Error(cdec->mLocation, EERR_DUPLICATE_DEFINITION, "Function already has a body");
|
||||||
|
|
||||||
|
@ -4001,7 +4022,7 @@ Expression* Parser::ParseDeclarationExpression(Declaration * pdec)
|
||||||
texp->mLeft = vexp;
|
texp->mLeft = vexp;
|
||||||
texp->mDecType = new Declaration(mScanner->mLocation, DT_TYPE_POINTER);
|
texp->mDecType = new Declaration(mScanner->mLocation, DT_TYPE_POINTER);
|
||||||
texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
||||||
texp->mDecType->mBase = pdec->mBase;
|
texp->mDecType->mBase = dec->mBase;
|
||||||
texp->mDecType->mSize = 2;
|
texp->mDecType->mSize = 2;
|
||||||
|
|
||||||
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
@ -4014,12 +4035,13 @@ Expression* Parser::ParseDeclarationExpression(Declaration * pdec)
|
||||||
|
|
||||||
Expression* aexp;
|
Expression* aexp;
|
||||||
|
|
||||||
if (dec->mBase->mCopyConstructor && !(dec->mValue->mType == EX_CALL && dec->mValue->mDecType->mType == DT_TYPE_STRUCT))
|
Declaration* fcons = dec->mBase->mScope->Lookup(dec->mBase->mIdent->PreMangle("+"));
|
||||||
|
|
||||||
|
if (fcons && !(dec->mValue->mType == EX_CALL && dec->mValue->mDecType->mType == DT_TYPE_STRUCT))
|
||||||
{
|
{
|
||||||
Declaration* mdec = dec->mBase->mCopyConstructor;
|
|
||||||
|
|
||||||
Expression* cexp = new Expression(dec->mLocation, EX_CONSTANT);
|
Expression* cexp = new Expression(dec->mLocation, EX_CONSTANT);
|
||||||
cexp->mDecValue = mdec;
|
cexp->mDecValue = fcons;
|
||||||
cexp->mDecType = cexp->mDecValue->mBase;
|
cexp->mDecType = cexp->mDecValue->mBase;
|
||||||
|
|
||||||
aexp = new Expression(mScanner->mLocation, EX_CALL);
|
aexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
|
@ -4027,6 +4049,8 @@ Expression* Parser::ParseDeclarationExpression(Declaration * pdec)
|
||||||
aexp->mRight = new Expression(dec->mLocation, EX_LIST);
|
aexp->mRight = new Expression(dec->mLocation, EX_LIST);
|
||||||
aexp->mRight->mLeft = texp;
|
aexp->mRight->mLeft = texp;
|
||||||
aexp->mRight->mRight = dec->mValue;
|
aexp->mRight->mRight = dec->mValue;
|
||||||
|
|
||||||
|
ResolveOverloadCall(aexp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -4710,6 +4734,8 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
|
||||||
dist += 4;
|
dist += 4;
|
||||||
else if (ptype->IsSame(ex->mDecType))
|
else if (ptype->IsSame(ex->mDecType))
|
||||||
;
|
;
|
||||||
|
else if (CanCoerceExpression(ex, ptype))
|
||||||
|
dist += 512;
|
||||||
else if (ptype->mType == DT_TYPE_REFERENCE && ptype->mBase->mType == DT_TYPE_STRUCT && etype->mType == DT_TYPE_STRUCT)
|
else if (ptype->mType == DT_TYPE_REFERENCE && ptype->mBase->mType == DT_TYPE_STRUCT && etype->mType == DT_TYPE_STRUCT)
|
||||||
{
|
{
|
||||||
int ncast = 0;
|
int ncast = 0;
|
||||||
|
@ -4771,12 +4797,52 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
|
||||||
return dist;
|
return dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Parser::CanCoerceExpression(Expression* exp, Declaration* type)
|
||||||
|
{
|
||||||
|
Declaration* tdec = exp->mDecType;
|
||||||
|
while (tdec->mType == DT_TYPE_REFERENCE)
|
||||||
|
tdec = tdec->mBase;
|
||||||
|
while (type->mType == DT_TYPE_REFERENCE)
|
||||||
|
type = type->mBase;
|
||||||
|
|
||||||
|
if (tdec->mType == DT_TYPE_STRUCT)
|
||||||
|
{
|
||||||
|
Declaration* fexp = tdec->mScope->Lookup(Ident::Unique("(cast)"));
|
||||||
|
if (fexp)
|
||||||
|
{
|
||||||
|
while (fexp && !fexp->mBase->mBase->IsSame(type))
|
||||||
|
fexp = fexp->mNext;
|
||||||
|
if (fexp)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type->mType == DT_TYPE_STRUCT)
|
||||||
|
{
|
||||||
|
if (!type->IsConstSame(tdec))
|
||||||
|
{
|
||||||
|
Declaration* fcons = type->mScope->Lookup(type->mIdent->PreMangle("+"));
|
||||||
|
if (fcons)
|
||||||
|
{
|
||||||
|
while (fcons && !(fcons->mBase->mParams && fcons->mBase->mParams->mNext && !fcons->mBase->mParams->mNext->mNext && fcons->mBase->mParams->mNext->mBase->CanAssign(tdec)))
|
||||||
|
fcons = fcons->mNext;
|
||||||
|
|
||||||
|
if (fcons)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Expression* Parser::CoerceExpression(Expression* exp, Declaration* type)
|
Expression* Parser::CoerceExpression(Expression* exp, Declaration* type)
|
||||||
{
|
{
|
||||||
Declaration* tdec = exp->mDecType;
|
Declaration* tdec = exp->mDecType;
|
||||||
while (tdec->mType == DT_TYPE_REFERENCE)
|
while (tdec->mType == DT_TYPE_REFERENCE)
|
||||||
tdec = tdec->mBase;
|
tdec = tdec->mBase;
|
||||||
|
while (type->mType == DT_TYPE_REFERENCE)
|
||||||
|
type = type->mBase;
|
||||||
|
|
||||||
if (tdec->mType == DT_TYPE_STRUCT)
|
if (tdec->mType == DT_TYPE_STRUCT)
|
||||||
{
|
{
|
||||||
|
@ -4802,6 +4868,78 @@ Expression* Parser::CoerceExpression(Expression* exp, Declaration* type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type->mType == DT_TYPE_STRUCT)
|
||||||
|
{
|
||||||
|
if (!type->IsConstSame(tdec))
|
||||||
|
{
|
||||||
|
Declaration* fcons = type->mScope->Lookup(type->mIdent->PreMangle("+"));
|
||||||
|
if (fcons)
|
||||||
|
{
|
||||||
|
while (fcons && !(fcons->mBase->mParams && fcons->mBase->mParams->mNext && !fcons->mBase->mParams->mNext->mNext && fcons->mBase->mParams->mNext->mBase->CanAssign(tdec)))
|
||||||
|
fcons = fcons->mNext;
|
||||||
|
|
||||||
|
if (fcons)
|
||||||
|
{
|
||||||
|
Declaration* vdec = new Declaration(mScanner->mLocation, DT_VARIABLE);
|
||||||
|
|
||||||
|
vdec->mBase = type->ToMutableType();
|
||||||
|
vdec->mVarIndex = mLocalIndex++;
|
||||||
|
vdec->mSize = type->mSize;
|
||||||
|
vdec->mFlags |= DTF_DEFINED;
|
||||||
|
|
||||||
|
Expression* vexp = new Expression(mScanner->mLocation, EX_VARIABLE);
|
||||||
|
vexp->mDecType = vdec->mBase;
|
||||||
|
vexp->mDecValue = vdec;
|
||||||
|
|
||||||
|
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
cexp->mDecValue = fcons;
|
||||||
|
cexp->mDecType = cexp->mDecValue->mBase;
|
||||||
|
|
||||||
|
Expression* fexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
|
fexp->mLeft = cexp;
|
||||||
|
|
||||||
|
fexp->mRight = exp;
|
||||||
|
|
||||||
|
Expression* texp = new Expression(mScanner->mLocation, EX_PREFIX);
|
||||||
|
texp->mToken = TK_BINARY_AND;
|
||||||
|
texp->mLeft = vexp;
|
||||||
|
texp->mDecType = new Declaration(mScanner->mLocation, DT_TYPE_POINTER);
|
||||||
|
texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
||||||
|
texp->mDecType->mBase = vdec->mBase;
|
||||||
|
texp->mDecType->mSize = 2;
|
||||||
|
|
||||||
|
Expression* lexp = new Expression(mScanner->mLocation, EX_LIST);
|
||||||
|
lexp->mLeft = texp;
|
||||||
|
lexp->mRight = fexp->mRight;
|
||||||
|
fexp->mRight = lexp;
|
||||||
|
|
||||||
|
Expression* dexp = nullptr;
|
||||||
|
if (type->mDestructor)
|
||||||
|
{
|
||||||
|
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
cexp->mDecValue = type->mDestructor;
|
||||||
|
cexp->mDecType = cexp->mDecValue->mBase;
|
||||||
|
|
||||||
|
dexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
|
dexp->mLeft = cexp;
|
||||||
|
dexp->mRight = texp;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expression* nexp = new Expression(mScanner->mLocation, EX_CONSTRUCT);
|
||||||
|
|
||||||
|
nexp->mLeft = new Expression(mScanner->mLocation, EX_LIST);
|
||||||
|
nexp->mLeft->mLeft = fexp;
|
||||||
|
nexp->mLeft->mRight = dexp;
|
||||||
|
|
||||||
|
nexp->mRight = vexp;
|
||||||
|
nexp->mDecType = vexp->mDecType;
|
||||||
|
|
||||||
|
return nexp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
|
@ -4817,13 +4955,19 @@ void Parser::CompleteFunctionDefaultParams(Expression* exp)
|
||||||
{
|
{
|
||||||
if (pexp)
|
if (pexp)
|
||||||
{
|
{
|
||||||
|
Expression* exp = pexp;
|
||||||
|
|
||||||
if (pexp->mType == EX_LIST)
|
if (pexp->mType == EX_LIST)
|
||||||
{
|
{
|
||||||
|
pexp->mLeft = CoerceExpression(pexp->mLeft, pdec->mBase);
|
||||||
lexp = pexp;
|
lexp = pexp;
|
||||||
pexp = pexp->mRight;
|
pexp = pexp->mRight;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
lexp->mRight = CoerceExpression(lexp->mRight, pdec->mBase);
|
||||||
pexp = nullptr;
|
pexp = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (pdec->mValue)
|
else if (pdec->mValue)
|
||||||
{
|
{
|
||||||
|
@ -4887,9 +5031,14 @@ Expression * Parser::ResolveOverloadCall(Expression* exp, Expression* exp2)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ibest == NOOVERLOAD)
|
if (ibest == NOOVERLOAD)
|
||||||
mErrors->Error(exp->mLocation, ERRO_NO_MATCHING_FUNCTION_CALL, "No matching function call");
|
{
|
||||||
|
#if _DEBUG
|
||||||
|
int d = OverloadDistance(exp->mLeft->mDecValue->mBase, exp->mRight);
|
||||||
|
#endif
|
||||||
|
mErrors->Error(exp->mLocation, ERRO_NO_MATCHING_FUNCTION_CALL, "No matching function call", exp->mLeft->mDecValue->mQualIdent);
|
||||||
|
}
|
||||||
else if (nbest > 1)
|
else if (nbest > 1)
|
||||||
mErrors->Error(exp->mLocation, ERRO_AMBIGUOUS_FUNCTION_CALL, "Ambiguous function call");
|
mErrors->Error(exp->mLocation, ERRO_AMBIGUOUS_FUNCTION_CALL, "Ambiguous function call", exp->mLeft->mDecValue->mQualIdent);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
exp->mLeft->mDecValue = dbest;
|
exp->mLeft->mDecValue = dbest;
|
||||||
|
@ -6831,6 +6980,69 @@ Expression* Parser::ParseSwitchStatement(void)
|
||||||
return sexp;
|
return sexp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Parser::ParseTemplate(void)
|
||||||
|
{
|
||||||
|
ConsumeToken(TK_LESS_THAN);
|
||||||
|
Declaration* tdec = new Declaration(mScanner->mLocation, DT_TEMPLATE);
|
||||||
|
Declaration* ppdec = nullptr;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
Declaration* pdec = nullptr;
|
||||||
|
|
||||||
|
if (ConsumeTokenIf(TK_CLASS))
|
||||||
|
{
|
||||||
|
if (mScanner->mToken == TK_IDENT)
|
||||||
|
{
|
||||||
|
Declaration* pdec = new Declaration(mScanner->mLocation, DT_ARGUMENT);
|
||||||
|
pdec->mIdent = mScanner->mTokenIdent;
|
||||||
|
pdec->mBase = TheVoidTypeDeclaration;
|
||||||
|
mScanner->NextToken();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Identifier expected");
|
||||||
|
}
|
||||||
|
else if (ConsumeTokenIf(TK_INT))
|
||||||
|
{
|
||||||
|
if (mScanner->mToken == TK_IDENT)
|
||||||
|
{
|
||||||
|
Declaration* pdec = new Declaration(mScanner->mLocation, DT_ARGUMENT);
|
||||||
|
pdec->mIdent = mScanner->mTokenIdent;
|
||||||
|
pdec->mBase = TheSignedIntTypeDeclaration;
|
||||||
|
mScanner->NextToken();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Identifier expected");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(mScanner->mLocation, EERR_TEMPLATE_PARAMS, "'class' or 'int' expected as template parameter");
|
||||||
|
|
||||||
|
if (pdec)
|
||||||
|
{
|
||||||
|
if (ppdec)
|
||||||
|
ppdec->mNext = pdec;
|
||||||
|
else
|
||||||
|
tdec->mParams = pdec;
|
||||||
|
ppdec = pdec;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ConsumeTokenIf(TK_COMMA))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConsumeToken(TK_GREATER_THAN);
|
||||||
|
|
||||||
|
if (mScanner->mToken == TK_CLASS)
|
||||||
|
{
|
||||||
|
// Class template
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Function template
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Expression* Parser::ParseAssemblerBaseOperand(Declaration* pcasm, int pcoffset)
|
Expression* Parser::ParseAssemblerBaseOperand(Declaration* pcasm, int pcoffset)
|
||||||
|
@ -7541,6 +7753,11 @@ void Parser::ParsePragma(void)
|
||||||
}
|
}
|
||||||
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(mScanner->mTokenIdent->mString, "once"))
|
||||||
|
{
|
||||||
|
mScanner->MarkSourceOnce();
|
||||||
|
mScanner->NextToken();
|
||||||
|
}
|
||||||
else if (!strcmp(mScanner->mTokenIdent->mString, "compile"))
|
else if (!strcmp(mScanner->mTokenIdent->mString, "compile"))
|
||||||
{
|
{
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
|
@ -8453,6 +8670,11 @@ void Parser::Parse(void)
|
||||||
}
|
}
|
||||||
else if (mScanner->mToken == TK_SEMICOLON)
|
else if (mScanner->mToken == TK_SEMICOLON)
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
|
else if (mScanner->mToken == TK_TEMPLATE)
|
||||||
|
{
|
||||||
|
mScanner->NextToken();
|
||||||
|
ParseTemplate();
|
||||||
|
}
|
||||||
else if (mScanner->mToken == TK_NAMESPACE)
|
else if (mScanner->mToken == TK_NAMESPACE)
|
||||||
{
|
{
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
|
|
|
@ -90,8 +90,11 @@ protected:
|
||||||
int OverloadDistance(Declaration* pdec, Expression* pexp);
|
int OverloadDistance(Declaration* pdec, Expression* pexp);
|
||||||
Expression * ResolveOverloadCall(Expression* exp, Expression * exp2 = nullptr);
|
Expression * ResolveOverloadCall(Expression* exp, Expression * exp2 = nullptr);
|
||||||
Expression* CoerceExpression(Expression* exp, Declaration* type);
|
Expression* CoerceExpression(Expression* exp, Declaration* type);
|
||||||
|
bool CanCoerceExpression(Expression* exp, Declaration* type);
|
||||||
void CompleteFunctionDefaultParams(Expression* exp);
|
void CompleteFunctionDefaultParams(Expression* exp);
|
||||||
|
|
||||||
|
void ParseTemplate(void);
|
||||||
|
|
||||||
Expression* ParseSimpleExpression(bool lhs);
|
Expression* ParseSimpleExpression(bool lhs);
|
||||||
Expression* ParsePrefixExpression(bool lhs);
|
Expression* ParsePrefixExpression(bool lhs);
|
||||||
Expression* ParsePostfixExpression(bool lhs);
|
Expression* ParsePostfixExpression(bool lhs);
|
||||||
|
|
|
@ -162,6 +162,7 @@ const char* TokenNames[] =
|
||||||
"'delete'",
|
"'delete'",
|
||||||
"'virtual'",
|
"'virtual'",
|
||||||
"'operator'",
|
"'operator'",
|
||||||
|
"'template'",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -306,6 +307,25 @@ Macro* MacroDict::Lookup(const Ident* ident)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TokenSequence::TokenSequence(Scanner* scanner)
|
||||||
|
: mNext(nullptr), mLocation(scanner->mLocation), mToken(scanner->mToken),
|
||||||
|
mTokenIdent(scanner->mTokenIdent), mTokenChar(scanner->mTokenChar),
|
||||||
|
mTokenInteger(scanner->mTokenInteger), mTokenNumber(scanner->mTokenNumber),
|
||||||
|
mTokenString(nullptr)
|
||||||
|
{
|
||||||
|
if (mToken == TK_STRING)
|
||||||
|
{
|
||||||
|
int ssize = strlen(scanner->mTokenString);
|
||||||
|
char * str = new char[ssize + 1];
|
||||||
|
strcpy_s(str, ssize + 1, scanner->mTokenString);
|
||||||
|
mTokenString = str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TokenSequence::~TokenSequence(void)
|
||||||
|
{
|
||||||
|
delete[] mTokenString;
|
||||||
|
}
|
||||||
|
|
||||||
Scanner::Scanner(Errors* errors, Preprocessor* preprocessor)
|
Scanner::Scanner(Errors* errors, Preprocessor* preprocessor)
|
||||||
: mErrors(errors), mPreprocessor(preprocessor)
|
: mErrors(errors), mPreprocessor(preprocessor)
|
||||||
|
@ -324,6 +344,9 @@ Scanner::Scanner(Errors* errors, Preprocessor* preprocessor)
|
||||||
mDefineArguments = nullptr;
|
mDefineArguments = nullptr;
|
||||||
mToken = TK_NONE;
|
mToken = TK_NONE;
|
||||||
mUngetToken = TK_NONE;
|
mUngetToken = TK_NONE;
|
||||||
|
mReplay = nullptr;
|
||||||
|
|
||||||
|
mOnceDict = new MacroDict();
|
||||||
|
|
||||||
NextChar();
|
NextChar();
|
||||||
|
|
||||||
|
@ -336,6 +359,18 @@ Scanner::~Scanner(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TokenSequence* Scanner::Record(void)
|
||||||
|
{
|
||||||
|
return new TokenSequence(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const TokenSequence* Scanner::Replay(const TokenSequence* replay)
|
||||||
|
{
|
||||||
|
const TokenSequence* seq = mReplay;
|
||||||
|
mReplay = replay;
|
||||||
|
return seq;
|
||||||
|
}
|
||||||
|
|
||||||
const char* Scanner::TokenName(Token token) const
|
const char* Scanner::TokenName(Token token) const
|
||||||
{
|
{
|
||||||
return TokenNames[token];
|
return TokenNames[token];
|
||||||
|
@ -412,8 +447,32 @@ void Scanner::AddMacro(const Ident* ident, const char* value)
|
||||||
mDefines->Insert(macro);
|
mDefines->Insert(macro);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Scanner::MarkSourceOnce(void)
|
||||||
|
{
|
||||||
|
const Ident* fident = Ident::Unique(mPreprocessor->mSource->mFileName);
|
||||||
|
|
||||||
|
Macro* macro = new Macro(fident, nullptr);
|
||||||
|
mOnceDict->Insert(macro);
|
||||||
|
}
|
||||||
|
|
||||||
void Scanner::NextToken(void)
|
void Scanner::NextToken(void)
|
||||||
{
|
{
|
||||||
|
if (mReplay)
|
||||||
|
{
|
||||||
|
mLocation = mReplay->mLocation;
|
||||||
|
mToken = mReplay->mToken;
|
||||||
|
|
||||||
|
mTokenIdent = mReplay->mTokenIdent;
|
||||||
|
mTokenChar = mReplay->mTokenChar;
|
||||||
|
mTokenNumber = mReplay->mTokenNumber;
|
||||||
|
mTokenInteger = mReplay->mTokenInteger;
|
||||||
|
if (mReplay->mTokenString)
|
||||||
|
strcpy_s(mTokenString, mReplay->mTokenString);
|
||||||
|
|
||||||
|
mReplay = mReplay->mNext;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
NextRawToken();
|
NextRawToken();
|
||||||
|
@ -503,6 +562,8 @@ void Scanner::NextToken(void)
|
||||||
{
|
{
|
||||||
if (!mPreprocessor->OpenSource("Including", mTokenString, true))
|
if (!mPreprocessor->OpenSource("Including", mTokenString, true))
|
||||||
mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Could not open source file", mTokenString);
|
mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Could not open source file", mTokenString);
|
||||||
|
else if (mOnceDict->Lookup(Ident::Unique(mPreprocessor->mSource->mFileName)))
|
||||||
|
mPreprocessor->CloseSource();
|
||||||
}
|
}
|
||||||
else if (mToken == TK_LESS_THAN)
|
else if (mToken == TK_LESS_THAN)
|
||||||
{
|
{
|
||||||
|
@ -510,6 +571,8 @@ void Scanner::NextToken(void)
|
||||||
StringToken('>', 'a');
|
StringToken('>', 'a');
|
||||||
if (!mPreprocessor->OpenSource("Including", mTokenString, false))
|
if (!mPreprocessor->OpenSource("Including", mTokenString, false))
|
||||||
mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Could not open source file", mTokenString);
|
mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Could not open source file", mTokenString);
|
||||||
|
else if (mOnceDict->Lookup(Ident::Unique(mPreprocessor->mSource->mFileName)))
|
||||||
|
mPreprocessor->CloseSource();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mToken == TK_PREP_DEFINE)
|
else if (mToken == TK_PREP_DEFINE)
|
||||||
|
@ -1426,6 +1489,8 @@ void Scanner::NextRawToken(void)
|
||||||
mToken = TK_DELETE;
|
mToken = TK_DELETE;
|
||||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "virtual"))
|
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "virtual"))
|
||||||
mToken = TK_VIRTUAL;
|
mToken = TK_VIRTUAL;
|
||||||
|
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "template"))
|
||||||
|
mToken = TK_TEMPLATE;
|
||||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "operator"))
|
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "operator"))
|
||||||
{
|
{
|
||||||
NextRawToken();
|
NextRawToken();
|
||||||
|
|
|
@ -161,6 +161,7 @@ enum Token
|
||||||
TK_DELETE,
|
TK_DELETE,
|
||||||
TK_VIRTUAL,
|
TK_VIRTUAL,
|
||||||
TK_OPERATOR,
|
TK_OPERATOR,
|
||||||
|
TK_TEMPLATE,
|
||||||
|
|
||||||
NUM_TOKENS
|
NUM_TOKENS
|
||||||
};
|
};
|
||||||
|
@ -204,6 +205,24 @@ protected:
|
||||||
MacroDict * mParent;
|
MacroDict * mParent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Scanner;
|
||||||
|
|
||||||
|
struct TokenSequence
|
||||||
|
{
|
||||||
|
TokenSequence * mNext;
|
||||||
|
Location mLocation;
|
||||||
|
Token mToken;
|
||||||
|
|
||||||
|
const Ident * mTokenIdent;
|
||||||
|
char mTokenChar;
|
||||||
|
const char * mTokenString;
|
||||||
|
double mTokenNumber;
|
||||||
|
int64 mTokenInteger;
|
||||||
|
|
||||||
|
TokenSequence(Scanner* scanner);
|
||||||
|
~TokenSequence(void);
|
||||||
|
};
|
||||||
|
|
||||||
class Scanner
|
class Scanner
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -214,6 +233,9 @@ public:
|
||||||
|
|
||||||
void NextToken(void);
|
void NextToken(void);
|
||||||
|
|
||||||
|
TokenSequence* Record(void);
|
||||||
|
const TokenSequence* Replay(const TokenSequence * sequence);
|
||||||
|
|
||||||
void Warning(const char * error);
|
void Warning(const char * error);
|
||||||
void Error(const char * error);
|
void Error(const char * error);
|
||||||
|
|
||||||
|
@ -247,6 +269,7 @@ public:
|
||||||
uint64 mCompilerOptions;
|
uint64 mCompilerOptions;
|
||||||
|
|
||||||
void AddMacro(const Ident* ident, const char* value);
|
void AddMacro(const Ident* ident, const char* value);
|
||||||
|
void MarkSourceOnce(void);
|
||||||
protected:
|
protected:
|
||||||
void NextRawToken(void);
|
void NextRawToken(void);
|
||||||
|
|
||||||
|
@ -261,10 +284,12 @@ protected:
|
||||||
|
|
||||||
int mMacroExpansionDepth;
|
int mMacroExpansionDepth;
|
||||||
|
|
||||||
MacroDict* mDefines, * mDefineArguments;
|
MacroDict* mDefines, * mDefineArguments, * mOnceDict;
|
||||||
|
|
||||||
Token mUngetToken;
|
Token mUngetToken;
|
||||||
|
|
||||||
|
const TokenSequence* mReplay;
|
||||||
|
|
||||||
void StringToken(char terminator, char mode);
|
void StringToken(char terminator, char mode);
|
||||||
void CharToken(char mode);
|
void CharToken(char mode);
|
||||||
bool NextChar(void);
|
bool NextChar(void);
|
||||||
|
|
Loading…
Reference in New Issue