Optimize global variable alias analysis

This commit is contained in:
drmortalwombat 2021-11-01 12:42:03 +01:00
parent 214ebd93f2
commit d3cba85efe
8 changed files with 215 additions and 132 deletions

View File

@ -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;

View File

@ -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];

View File

@ -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;

View File

@ -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();

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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;