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",
|
||||||
|
@ -138,7 +139,7 @@ const char* TokenNames[] = {
|
||||||
|
|
||||||
|
|
||||||
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