Optimize global variable alias analysis
This commit is contained in:
parent
214ebd93f2
commit
d3cba85efe
|
@ -72,6 +72,8 @@ static const uint32 DTF_FUNC_ASSEMBLER = 0x00080000;
|
||||||
static const uint32 DTF_FUNC_RECURSIVE = 0x00100000;
|
static const uint32 DTF_FUNC_RECURSIVE = 0x00100000;
|
||||||
static const uint32 DTF_FUNC_ANALYZING = 0x00200000;
|
static const uint32 DTF_FUNC_ANALYZING = 0x00200000;
|
||||||
|
|
||||||
|
static const uint32 DTF_VAR_ALIASING = 0x00400000;
|
||||||
|
|
||||||
|
|
||||||
class Declaration;
|
class Declaration;
|
||||||
|
|
||||||
|
|
|
@ -535,6 +535,13 @@ int Emulator::Emulate(int startIP)
|
||||||
mIP = mMemory[0x100 + mRegS] + 256 * mMemory[0x101 + mRegS] + 1;
|
mIP = mMemory[0x100 + mRegS] + 256 * mMemory[0x101 + mRegS] + 1;
|
||||||
mRegS += 2;
|
mRegS += 2;
|
||||||
}
|
}
|
||||||
|
else if (mIP == 0xffcf)
|
||||||
|
{
|
||||||
|
int ch = getchar();
|
||||||
|
mRegA = ch;
|
||||||
|
mIP = mMemory[0x100 + mRegS] + 256 * mMemory[0x101 + mRegS] + 1;
|
||||||
|
mRegS += 2;
|
||||||
|
}
|
||||||
|
|
||||||
uint8 opcode = mMemory[mIP];
|
uint8 opcode = mMemory[mIP];
|
||||||
AsmInsData d = DecInsData[opcode];
|
AsmInsData d = DecInsData[opcode];
|
||||||
|
|
|
@ -280,6 +280,12 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
|
||||||
case EX_PREINCDEC:
|
case EX_PREINCDEC:
|
||||||
return Analyze(exp->mLeft, procDec);
|
return Analyze(exp->mLeft, procDec);
|
||||||
case EX_PREFIX:
|
case EX_PREFIX:
|
||||||
|
ldec = Analyze(exp->mLeft, procDec);
|
||||||
|
if (exp->mToken == TK_BINARY_AND)
|
||||||
|
{
|
||||||
|
if (ldec->mType == DT_VARIABLE)
|
||||||
|
ldec->mFlags |= DTF_VAR_ALIASING;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case EX_POSTFIX:
|
case EX_POSTFIX:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -433,7 +433,7 @@ static bool MemRange(const InterInstruction * ins, const GrowingInstructionPtrAr
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool StoreAliasing(const InterInstruction * lins, const InterInstruction* sins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams)
|
static bool StoreAliasing(const InterInstruction * lins, const InterInstruction* sins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, const GrowingVariableArray& staticVars)
|
||||||
{
|
{
|
||||||
InterMemory lmem, smem;
|
InterMemory lmem, smem;
|
||||||
int lvindex, svindex;
|
int lvindex, svindex;
|
||||||
|
@ -457,6 +457,8 @@ static bool StoreAliasing(const InterInstruction * lins, const InterInstruction*
|
||||||
return aliasedLocals[lvindex];
|
return aliasedLocals[lvindex];
|
||||||
else if (lmem == IM_PARAM || lmem == IM_FPARAM)
|
else if (lmem == IM_PARAM || lmem == IM_FPARAM)
|
||||||
return aliasedParams[lvindex];
|
return aliasedParams[lvindex];
|
||||||
|
else if (lmem == IM_GLOBAL)
|
||||||
|
return staticVars[lvindex]->mAliased;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -514,7 +516,7 @@ bool InterInstruction::IsEqual(const InterInstruction* ins) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams)
|
void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, const GrowingVariableArray& staticVars)
|
||||||
{
|
{
|
||||||
int i, value, temp;
|
int i, value, temp;
|
||||||
|
|
||||||
|
@ -609,7 +611,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < mNum)
|
while (i < mNum)
|
||||||
{
|
{
|
||||||
if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], ins, tvalue, aliasedLocals, aliasedParams))
|
if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], ins, tvalue, aliasedLocals, aliasedParams, staticVars))
|
||||||
{
|
{
|
||||||
mNum--;
|
mNum--;
|
||||||
if (mNum > 0)
|
if (mNum > 0)
|
||||||
|
@ -627,7 +629,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < mNum)
|
while (i < mNum)
|
||||||
{
|
{
|
||||||
if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], ins, tvalue, aliasedLocals, aliasedParams))
|
if ((mInstructions[i]->mCode == IC_LOAD || mInstructions[i]->mCode == IC_STORE) && StoreAliasing(mInstructions[i], ins, tvalue, aliasedLocals, aliasedParams, staticVars))
|
||||||
{
|
{
|
||||||
mNum--;
|
mNum--;
|
||||||
if (mNum > 0)
|
if (mNum > 0)
|
||||||
|
@ -787,7 +789,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
|
||||||
ins->mSrc[0].mTemp = -1;
|
ins->mSrc[0].mTemp = -1;
|
||||||
ins->mSrc[1].mTemp = -1;
|
ins->mSrc[1].mTemp = -1;
|
||||||
|
|
||||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -806,7 +808,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
|
||||||
ins->mSrc[1].mTemp = -1;
|
ins->mSrc[1].mTemp = -1;
|
||||||
assert(ins->mSrc[0].mTemp >= 0);
|
assert(ins->mSrc[0].mTemp >= 0);
|
||||||
|
|
||||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -817,7 +819,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
|
||||||
ins->mSrc[0].mTemp = -1;
|
ins->mSrc[0].mTemp = -1;
|
||||||
ins->mSrc[1].mTemp = -1;
|
ins->mSrc[1].mTemp = -1;
|
||||||
|
|
||||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -832,7 +834,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
|
||||||
ins->mSrc[1].mTemp = -1;
|
ins->mSrc[1].mTemp = -1;
|
||||||
assert(ins->mSrc[0].mTemp >= 0);
|
assert(ins->mSrc[0].mTemp >= 0);
|
||||||
|
|
||||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -844,7 +846,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
|
||||||
ins->mSrc[0].mTemp = -1;
|
ins->mSrc[0].mTemp = -1;
|
||||||
ins->mSrc[1].mTemp = -1;
|
ins->mSrc[1].mTemp = -1;
|
||||||
|
|
||||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -854,7 +856,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
|
||||||
ins->mOperator = IA_NEG;
|
ins->mOperator = IA_NEG;
|
||||||
ins->mSrc[1].mTemp = -1;
|
ins->mSrc[1].mTemp = -1;
|
||||||
|
|
||||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -868,7 +870,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
|
||||||
ins->mSrc[0].mTemp = -1;
|
ins->mSrc[0].mTemp = -1;
|
||||||
ins->mSrc[1].mTemp = -1;
|
ins->mSrc[1].mTemp = -1;
|
||||||
|
|
||||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -878,7 +880,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
|
||||||
ins->mSrc[1].mTemp = -1;
|
ins->mSrc[1].mTemp = -1;
|
||||||
assert(ins->mSrc[0].mTemp >= 0);
|
assert(ins->mSrc[0].mTemp >= 0);
|
||||||
|
|
||||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1093,7 +1095,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
|
||||||
ins->mSrc[0].mTemp = -1;
|
ins->mSrc[0].mTemp = -1;
|
||||||
ins->mSrc[1].mTemp = -1;
|
ins->mSrc[1].mTemp = -1;
|
||||||
|
|
||||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IT_POINTER:
|
case IT_POINTER:
|
||||||
|
@ -1107,7 +1109,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
|
||||||
ins->mSrc[0].mTemp = -1;
|
ins->mSrc[0].mTemp = -1;
|
||||||
ins->mSrc[1].mTemp = -1;
|
ins->mSrc[1].mTemp = -1;
|
||||||
|
|
||||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
|
||||||
}
|
}
|
||||||
else if (ins->mSrc[1].mTemp == ins->mSrc[0].mTemp)
|
else if (ins->mSrc[1].mTemp == ins->mSrc[0].mTemp)
|
||||||
{
|
{
|
||||||
|
@ -1133,7 +1135,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
|
||||||
ins->mSrc[0].mTemp = -1;
|
ins->mSrc[0].mTemp = -1;
|
||||||
ins->mSrc[1].mTemp = -1;
|
ins->mSrc[1].mTemp = -1;
|
||||||
|
|
||||||
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams);
|
UpdateValue(ins, tvalue, aliasedLocals, aliasedParams, staticVars);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1298,7 +1300,11 @@ void InterInstruction::FilterStaticVarsUsage(const GrowingVariableArray& staticV
|
||||||
{
|
{
|
||||||
if (mSrc[0].mMemory == IM_INDIRECT)
|
if (mSrc[0].mMemory == IM_INDIRECT)
|
||||||
{
|
{
|
||||||
requiredVars.OrNot(providedVars);
|
for (int i = 0; i < staticVars.Size(); i++)
|
||||||
|
{
|
||||||
|
if (staticVars[i]->mAliased && !providedVars[i])
|
||||||
|
requiredVars += i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (mSrc[0].mMemory == IM_GLOBAL)
|
else if (mSrc[0].mMemory == IM_GLOBAL)
|
||||||
{
|
{
|
||||||
|
@ -1310,7 +1316,11 @@ void InterInstruction::FilterStaticVarsUsage(const GrowingVariableArray& staticV
|
||||||
{
|
{
|
||||||
if (mSrc[1].mMemory == IM_INDIRECT)
|
if (mSrc[1].mMemory == IM_INDIRECT)
|
||||||
{
|
{
|
||||||
requiredVars.OrNot(providedVars);
|
for (int i = 0; i < staticVars.Size(); i++)
|
||||||
|
{
|
||||||
|
if (staticVars[i]->mAliased && !providedVars[i])
|
||||||
|
requiredVars += i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (mSrc[1].mMemory == IM_GLOBAL)
|
else if (mSrc[1].mMemory == IM_GLOBAL)
|
||||||
{
|
{
|
||||||
|
@ -1565,7 +1575,11 @@ bool InterInstruction::RemoveUnusedStaticStoreInstructions(const GrowingVariable
|
||||||
{
|
{
|
||||||
if (mSrc[0].mMemory == IM_INDIRECT)
|
if (mSrc[0].mMemory == IM_INDIRECT)
|
||||||
{
|
{
|
||||||
requiredVars.Fill();
|
for (int i = 0; i < staticVars.Size(); i++)
|
||||||
|
{
|
||||||
|
if (staticVars[i]->mAliased)
|
||||||
|
requiredVars += i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (mSrc[0].mMemory == IM_GLOBAL)
|
else if (mSrc[0].mMemory == IM_GLOBAL)
|
||||||
{
|
{
|
||||||
|
@ -3185,7 +3199,7 @@ bool InterCodeBasicBlock::RemoveUnusedStoreInstructions(const GrowingVariableArr
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, int& spareTemps)
|
void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, int& spareTemps, const GrowingVariableArray& staticVars)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -3441,12 +3455,12 @@ void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArra
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
lvalues.UpdateValue(mInstructions[i], ltvalue, aliasedLocals, aliasedParams);
|
lvalues.UpdateValue(mInstructions[i], ltvalue, aliasedLocals, aliasedParams, staticVars);
|
||||||
mInstructions[i]->PerformValueForwarding(ltvalue, tvalid);
|
mInstructions[i]->PerformValueForwarding(ltvalue, tvalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTrueJump) mTrueJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams, spareTemps);
|
if (mTrueJump) mTrueJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams, spareTemps, staticVars);
|
||||||
if (mFalseJump) mFalseJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams, spareTemps);
|
if (mFalseJump) mFalseJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams, spareTemps, staticVars);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4885,7 +4899,7 @@ void InterCodeProcedure::Close(void)
|
||||||
tvalidSet.Reset(numTemps + 32);
|
tvalidSet.Reset(numTemps + 32);
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->PerformValueForwarding(mValueForwardingTable, valueSet, tvalidSet, mLocalAliasedSet, mParamAliasedSet, numTemps);
|
mEntryBlock->PerformValueForwarding(mValueForwardingTable, valueSet, tvalidSet, mLocalAliasedSet, mParamAliasedSet, numTemps, mModule->mGlobalVars);
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
eliminated = mEntryBlock->EliminateDeadBranches();
|
eliminated = mEntryBlock->EliminateDeadBranches();
|
||||||
|
|
|
@ -148,7 +148,7 @@ public:
|
||||||
void RemoveValue(int index);
|
void RemoveValue(int index);
|
||||||
void InsertValue(InterInstruction * ins);
|
void InsertValue(InterInstruction * ins);
|
||||||
|
|
||||||
void UpdateValue(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams);
|
void UpdateValue(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, const GrowingVariableArray& staticVars);
|
||||||
void Intersect(ValueSet& set);
|
void Intersect(ValueSet& set);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -475,7 +475,7 @@ public:
|
||||||
|
|
||||||
void CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue);
|
void CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue);
|
||||||
void PerformTempForwarding(TempForwardingTable& forwardingTable);
|
void PerformTempForwarding(TempForwardingTable& forwardingTable);
|
||||||
void PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, int & spareTemps);
|
void PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, int & spareTemps, const GrowingVariableArray& staticVars);
|
||||||
void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid);
|
void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid);
|
||||||
bool EliminateDeadBranches(void);
|
bool EliminateDeadBranches(void);
|
||||||
|
|
||||||
|
|
|
@ -837,6 +837,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
var->mIdent = dec->mIdent;
|
var->mIdent = dec->mIdent;
|
||||||
var->mOffset = 0;
|
var->mOffset = 0;
|
||||||
var->mSize = dec->mSize;
|
var->mSize = dec->mSize;
|
||||||
|
if ((dec->mFlags & DTF_VAR_ALIASING) || dec->mBase->mType == DT_TYPE_ARRAY)
|
||||||
|
var->mAliased = true;
|
||||||
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA);
|
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA);
|
||||||
dec->mLinkerObject = var->mLinkerObject;
|
dec->mLinkerObject = var->mLinkerObject;
|
||||||
var->mLinkerObject->AddData(dec->mData, dec->mSize);
|
var->mLinkerObject->AddData(dec->mData, dec->mSize);
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
#include "MachineTypes.h"
|
#include "MachineTypes.h"
|
||||||
|
|
||||||
|
|
||||||
const char* TokenNames[] = {
|
const char* TokenNames[] =
|
||||||
|
{
|
||||||
"tk_none",
|
"tk_none",
|
||||||
"tk_eof",
|
"tk_eof",
|
||||||
"tk_error",
|
"tk_error",
|
||||||
|
@ -16,129 +17,129 @@ const char* TokenNames[] = {
|
||||||
"'else'",
|
"'else'",
|
||||||
"'while'",
|
"'while'",
|
||||||
"'do'",
|
"'do'",
|
||||||
"'for'",
|
"'for'",
|
||||||
"'void'",
|
"'void'",
|
||||||
"'int'",
|
"'int'",
|
||||||
"'char'",
|
"'char'",
|
||||||
"'float'",
|
"'float'",
|
||||||
"'unsigned'",
|
"'unsigned'",
|
||||||
"'signed'",
|
"'signed'",
|
||||||
"'switch'",
|
"'switch'",
|
||||||
"'case'",
|
"'case'",
|
||||||
"'default'",
|
"'default'",
|
||||||
"'break'",
|
"'break'",
|
||||||
"'return'",
|
"'return'",
|
||||||
"'short'",
|
"'short'",
|
||||||
"'long'",
|
"'long'",
|
||||||
"'continue'",
|
"'continue'",
|
||||||
"'integer'",
|
"'integer'",
|
||||||
"'integeru'",
|
"'integeru'",
|
||||||
"'integerl'",
|
"'integerl'",
|
||||||
"'integerul'",
|
"'integerul'",
|
||||||
"'bool'",
|
"'bool'",
|
||||||
"'const'",
|
"'const'",
|
||||||
"'volatile'",
|
"'volatile'",
|
||||||
"'typedef'",
|
"'typedef'",
|
||||||
"'struct'",
|
"'struct'",
|
||||||
"'union'",
|
"'union'",
|
||||||
"'enum'",
|
"'enum'",
|
||||||
"'sizeof'",
|
"'sizeof'",
|
||||||
"'static'",
|
"'static'",
|
||||||
"'extern'",
|
"'extern'",
|
||||||
"'inline'",
|
"'inline'",
|
||||||
|
|
||||||
"__asm",
|
"__asm",
|
||||||
|
|
||||||
"number",
|
"number",
|
||||||
"char",
|
"char",
|
||||||
"string literal",
|
"string literal",
|
||||||
"identifier",
|
"identifier",
|
||||||
"'true'",
|
"'true'",
|
||||||
"'false'",
|
"'false'",
|
||||||
"'nullptr'",
|
"'nullptr'",
|
||||||
|
|
||||||
"'+'",
|
"'+'",
|
||||||
"'-'",
|
"'-'",
|
||||||
"'*'",
|
"'*'",
|
||||||
"'/'",
|
"'/'",
|
||||||
"'%'",
|
"'%'",
|
||||||
|
|
||||||
"'<<'",
|
"'<<'",
|
||||||
"'>>'",
|
"'>>'",
|
||||||
|
|
||||||
"'++'",
|
"'++'",
|
||||||
"'--'",
|
"'--'",
|
||||||
|
|
||||||
"'!'",
|
"'!'",
|
||||||
"'&&'",
|
"'&&'",
|
||||||
"'||'",
|
"'||'",
|
||||||
|
|
||||||
"'~'",
|
"'~'",
|
||||||
"'&'",
|
"'&'",
|
||||||
"'|'",
|
"'|'",
|
||||||
"'^'",
|
"'^'",
|
||||||
|
|
||||||
"'=='",
|
"'=='",
|
||||||
"'!='",
|
"'!='",
|
||||||
"'>'",
|
"'>'",
|
||||||
"'>='",
|
"'>='",
|
||||||
"'<'",
|
"'<'",
|
||||||
"'<='",
|
"'<='",
|
||||||
|
|
||||||
"'='",
|
"'='",
|
||||||
"'+='",
|
"'+='",
|
||||||
"'-='",
|
"'-='",
|
||||||
"'*='",
|
"'*='",
|
||||||
"'/='",
|
"'/='",
|
||||||
"'%='",
|
"'%='",
|
||||||
"'<<='",
|
"'<<='",
|
||||||
"'>>='",
|
"'>>='",
|
||||||
"'&='",
|
"'&='",
|
||||||
"'^='",
|
"'^='",
|
||||||
"'|='",
|
"'|='",
|
||||||
|
|
||||||
"'->'",
|
"'->'",
|
||||||
"'#'",
|
"'#'",
|
||||||
"'$'",
|
"'$'",
|
||||||
|
|
||||||
"'('",
|
"'('",
|
||||||
"')'",
|
"')'",
|
||||||
|
|
||||||
"'{'",
|
"'{'",
|
||||||
"'}'",
|
"'}'",
|
||||||
|
|
||||||
"'['",
|
"'['",
|
||||||
"']'",
|
"']'",
|
||||||
|
|
||||||
"'.'",
|
"'.'",
|
||||||
"'..'",
|
"'..'",
|
||||||
"'...'",
|
"'...'",
|
||||||
"','",
|
"','",
|
||||||
"';'",
|
"';'",
|
||||||
"':'",
|
"':'",
|
||||||
"'?'",
|
"'?'",
|
||||||
|
|
||||||
"embedded",
|
"embedded",
|
||||||
|
|
||||||
"'#define'",
|
"'#define'",
|
||||||
"'#include'",
|
"'#include'",
|
||||||
"'#if'",
|
"'#if'",
|
||||||
"'#elif'",
|
"'#elif'",
|
||||||
"'#else'",
|
"'#else'",
|
||||||
"'#endif'",
|
"'#endif'",
|
||||||
"'#ifdef'",
|
"'#ifdef'",
|
||||||
"'#ifndef'",
|
"'#ifndef'",
|
||||||
"'#pragma'",
|
"'#pragma'",
|
||||||
|
|
||||||
"'#assign'",
|
"'#assign'",
|
||||||
"'#repeat'",
|
"'#repeat'",
|
||||||
"'#until'",
|
"'#until'",
|
||||||
"'#embed'"
|
"'#embed'"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Macro::Macro(const Ident* ident)
|
Macro::Macro(const Ident* ident)
|
||||||
: mIdent(ident), mString(nullptr), mNumArguments(0)
|
: mIdent(ident), mString(nullptr), mNumArguments(-1)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -471,6 +472,8 @@ void Scanner::NextToken(void)
|
||||||
|
|
||||||
if (mTokenChar == '(')
|
if (mTokenChar == '(')
|
||||||
{
|
{
|
||||||
|
macro->mNumArguments = 0;
|
||||||
|
|
||||||
NextRawToken();
|
NextRawToken();
|
||||||
|
|
||||||
if (mTokenChar == ')')
|
if (mTokenChar == ')')
|
||||||
|
@ -635,7 +638,21 @@ void Scanner::NextToken(void)
|
||||||
{
|
{
|
||||||
MacroExpansion* ex = new MacroExpansion();
|
MacroExpansion* ex = new MacroExpansion();
|
||||||
ex->mDefinedArguments = mDefineArguments;
|
ex->mDefinedArguments = mDefineArguments;
|
||||||
if (def->mNumArguments)
|
|
||||||
|
if (def->mNumArguments == 0)
|
||||||
|
{
|
||||||
|
NextRawToken();
|
||||||
|
if (mToken != TK_OPEN_PARENTHESIS)
|
||||||
|
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Missing '(' for macro expansion");
|
||||||
|
else
|
||||||
|
NextRawToken();
|
||||||
|
if (mToken != TK_CLOSE_PARENTHESIS)
|
||||||
|
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Missing ')' for macro expansion");
|
||||||
|
else
|
||||||
|
NextRawToken();
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (def->mNumArguments > 0)
|
||||||
{
|
{
|
||||||
mDefineArguments = new MacroDict();
|
mDefineArguments = new MacroDict();
|
||||||
NextRawToken();
|
NextRawToken();
|
||||||
|
@ -712,9 +729,8 @@ void Scanner::NextRawToken(void)
|
||||||
{
|
{
|
||||||
if (mToken != TK_EOF)
|
if (mToken != TK_EOF)
|
||||||
{
|
{
|
||||||
Token pt = mToken;
|
|
||||||
|
|
||||||
mToken = TK_ERROR;
|
mToken = TK_ERROR;
|
||||||
|
mStartOfLine = false;
|
||||||
|
|
||||||
while (IsWhitespace(mTokenChar))
|
while (IsWhitespace(mTokenChar))
|
||||||
{
|
{
|
||||||
|
@ -1011,7 +1027,7 @@ void Scanner::NextRawToken(void)
|
||||||
|
|
||||||
case '#':
|
case '#':
|
||||||
{
|
{
|
||||||
if (!(mAssemblerMode || mPrepCondFalse) || mOffset == 1)
|
if (!(mAssemblerMode || mPrepCondFalse) || mOffset == 1 || mStartOfLine)
|
||||||
{
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
char tkprep[128];
|
char tkprep[128];
|
||||||
|
@ -1375,6 +1391,7 @@ bool Scanner::NextChar(void)
|
||||||
else if (mPreprocessor->NextLine())
|
else if (mPreprocessor->NextLine())
|
||||||
{
|
{
|
||||||
mOffset = 0;
|
mOffset = 0;
|
||||||
|
mStartOfLine = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1603,6 +1620,40 @@ int64 Scanner::PrepParseSimple(void)
|
||||||
else
|
else
|
||||||
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "')' expected");
|
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "')' expected");
|
||||||
break;
|
break;
|
||||||
|
case TK_IDENT:
|
||||||
|
if (strcmp(mTokenIdent->mString, "defined") == 0)
|
||||||
|
{
|
||||||
|
NextToken();
|
||||||
|
if (mToken == TK_OPEN_PARENTHESIS)
|
||||||
|
{
|
||||||
|
NextRawToken();
|
||||||
|
if (mToken == TK_IDENT)
|
||||||
|
{
|
||||||
|
Macro* def = nullptr;
|
||||||
|
if (mDefineArguments)
|
||||||
|
def = mDefineArguments->Lookup(mTokenIdent);
|
||||||
|
if (!def)
|
||||||
|
def = mDefines->Lookup(mTokenIdent);
|
||||||
|
if (def)
|
||||||
|
v = 1;
|
||||||
|
else
|
||||||
|
v = 0;
|
||||||
|
NextToken();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Identifier expected");
|
||||||
|
|
||||||
|
if (mToken == TK_CLOSE_PARENTHESIS)
|
||||||
|
NextToken();
|
||||||
|
else
|
||||||
|
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "')' expected");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "'(' expected");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Invalid preprocessor symbol", mTokenIdent->mString);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Invalid preprocessor token", TokenName(mToken));
|
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Invalid preprocessor token", TokenName(mToken));
|
||||||
if (mToken != TK_EOL)
|
if (mToken != TK_EOL)
|
||||||
|
|
|
@ -192,6 +192,7 @@ public:
|
||||||
|
|
||||||
int mOffset;
|
int mOffset;
|
||||||
const char * mLine;
|
const char * mLine;
|
||||||
|
bool mStartOfLine;
|
||||||
|
|
||||||
const Ident * mTokenIdent;
|
const Ident * mTokenIdent;
|
||||||
char mTokenString[1024], mTokenChar;
|
char mTokenString[1024], mTokenChar;
|
||||||
|
|
Loading…
Reference in New Issue