Improve cpp code generation
This commit is contained in:
parent
18c21b3fda
commit
9cdfad7d34
|
@ -44,6 +44,18 @@ string::string(const char * s)
|
||||||
cstr = nullptr;
|
cstr = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string::string(const char * s, char size)
|
||||||
|
{
|
||||||
|
if (size)
|
||||||
|
{
|
||||||
|
cstr = malloc(char(size + 2));
|
||||||
|
cstr[0] = size;
|
||||||
|
smemcpy(cstr + 1, s, size + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cstr = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
string::string(char c)
|
string::string(char c)
|
||||||
{
|
{
|
||||||
cstr = malloc(3);
|
cstr = malloc(3);
|
||||||
|
@ -64,6 +76,11 @@ string::~string(void)
|
||||||
free(cstr);
|
free(cstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void string::copyseg(char * p, char at, char num) const
|
||||||
|
{
|
||||||
|
smemcpy(p, cstr + 1 + at, num);
|
||||||
|
}
|
||||||
|
|
||||||
string & string::operator=(const string & s)
|
string & string::operator=(const string & s)
|
||||||
{
|
{
|
||||||
if (cstr != s.cstr)
|
if (cstr != s.cstr)
|
||||||
|
|
|
@ -10,6 +10,7 @@ public:
|
||||||
string(void);
|
string(void);
|
||||||
string(const string & s);
|
string(const string & s);
|
||||||
string(const char * s);
|
string(const char * s);
|
||||||
|
string(const char * s, char size);
|
||||||
string(char c);
|
string(char c);
|
||||||
~string(void);
|
~string(void);
|
||||||
|
|
||||||
|
@ -61,6 +62,8 @@ public:
|
||||||
int find(const string & s, char pos) const;
|
int find(const string & s, char pos) const;
|
||||||
int find(const char * s, char pos) const;
|
int find(const char * s, char pos) const;
|
||||||
int find(char c, char pos) const;
|
int find(char c, char pos) const;
|
||||||
|
|
||||||
|
void copyseg(char * p, char at, char num) const;
|
||||||
protected:
|
protected:
|
||||||
string(char l, char * b);
|
string(char l, char * b);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1238,6 +1238,31 @@ bool Declaration::IsSameParams(const Declaration* dec) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Declaration::IsDerivedFrom(const Declaration* dec) const
|
||||||
|
{
|
||||||
|
if (mType != DT_TYPE_FUNCTION || dec->mType != DT_TYPE_FUNCTION)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!(mFlags & DTF_FUNC_THIS) || !(dec->mFlags & DTF_FUNC_THIS))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!mBase->IsSame(dec->mBase))
|
||||||
|
return false;
|
||||||
|
Declaration* dl = mParams->mNext, * dr = dec->mParams->mNext;
|
||||||
|
while (dl && dr)
|
||||||
|
{
|
||||||
|
if (!dl->mBase->IsSame(dr->mBase))
|
||||||
|
return false;
|
||||||
|
dl = dl->mNext;
|
||||||
|
dr = dr->mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dl || dr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Declaration::IsSame(const Declaration* dec) const
|
bool Declaration::IsSame(const Declaration* dec) const
|
||||||
{
|
{
|
||||||
if (this == dec)
|
if (this == dec)
|
||||||
|
|
|
@ -262,6 +262,7 @@ public:
|
||||||
|
|
||||||
bool CanAssign(const Declaration* fromType) const;
|
bool CanAssign(const Declaration* fromType) const;
|
||||||
bool IsSame(const Declaration* dec) const;
|
bool IsSame(const Declaration* dec) const;
|
||||||
|
bool IsDerivedFrom(const Declaration* dec) const;
|
||||||
bool IsSubType(const Declaration* dec) const;
|
bool IsSubType(const Declaration* dec) const;
|
||||||
bool IsConstSame(const Declaration* dec) const;
|
bool IsConstSame(const Declaration* dec) const;
|
||||||
bool IsSameValue(const Declaration* dec) const;
|
bool IsSameValue(const Declaration* dec) const;
|
||||||
|
|
|
@ -284,7 +284,7 @@ void GlobalAnalyzer::MarkRecursions(void)
|
||||||
|
|
||||||
void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
|
void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
|
||||||
{
|
{
|
||||||
if (!(procDec->mBase->mFlags & DTF_FASTCALL) && !(procDec->mBase->mFlags & DTF_STACKCALL) && (procDec->mType == DT_CONST_FUNCTION) && !(procDec->mFlags & DTF_FUNC_ANALYZING))
|
if (!(procDec->mBase->mFlags & DTF_FASTCALL) && (procDec->mType == DT_CONST_FUNCTION) && !(procDec->mFlags & DTF_FUNC_ANALYZING))
|
||||||
{
|
{
|
||||||
procDec->mFlags |= DTF_FUNC_ANALYZING;
|
procDec->mFlags |= DTF_FUNC_ANALYZING;
|
||||||
int nbase = 0;
|
int nbase = 0;
|
||||||
|
|
|
@ -15331,7 +15331,7 @@ InterCodeProcedure::InterCodeProcedure(InterCodeModule * mod, const Location & l
|
||||||
mNativeProcedure(false), mLeafProcedure(false), mCallsFunctionPointer(false), mCalledFunctions(nullptr), mFastCallProcedure(false),
|
mNativeProcedure(false), mLeafProcedure(false), mCallsFunctionPointer(false), mCalledFunctions(nullptr), mFastCallProcedure(false),
|
||||||
mInterrupt(false), mHardwareInterrupt(false), mCompiled(false), mInterruptCalled(false), mDynamicStack(false),
|
mInterrupt(false), mHardwareInterrupt(false), mCompiled(false), mInterruptCalled(false), mDynamicStack(false),
|
||||||
mSaveTempsLinkerObject(nullptr), mValueReturn(false), mFramePointer(false),
|
mSaveTempsLinkerObject(nullptr), mValueReturn(false), mFramePointer(false),
|
||||||
mCheckUnreachable(true),
|
mCheckUnreachable(true), mReturnType(IT_NONE),
|
||||||
mDeclaration(nullptr)
|
mDeclaration(nullptr)
|
||||||
{
|
{
|
||||||
mID = mModule->mProcedures.Size();
|
mID = mModule->mProcedures.Size();
|
||||||
|
|
|
@ -604,7 +604,7 @@ public:
|
||||||
|
|
||||||
LinkerObject * mLinkerObject, * mSaveTempsLinkerObject;
|
LinkerObject * mLinkerObject, * mSaveTempsLinkerObject;
|
||||||
Declaration * mDeclaration;
|
Declaration * mDeclaration;
|
||||||
|
InterType mReturnType;
|
||||||
uint64 mCompilerOptions;
|
uint64 mCompilerOptions;
|
||||||
|
|
||||||
InterCodeProcedure(InterCodeModule * module, const Location & location, const Ident * ident, LinkerObject* linkerObject);
|
InterCodeProcedure(InterCodeModule * module, const Location & location, const Ident * ident, LinkerObject* linkerObject);
|
||||||
|
|
|
@ -4591,6 +4591,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
|
||||||
|
|
||||||
proc->mCompilerOptions = mCompilerOptions;
|
proc->mCompilerOptions = mCompilerOptions;
|
||||||
|
|
||||||
|
|
||||||
dec->mVarIndex = proc->mID;
|
dec->mVarIndex = proc->mID;
|
||||||
dec->mLinkerObject = proc->mLinkerObject;
|
dec->mLinkerObject = proc->mLinkerObject;
|
||||||
proc->mNumLocals = dec->mNumVars;
|
proc->mNumLocals = dec->mNumVars;
|
||||||
|
@ -4632,7 +4633,10 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
|
||||||
proc->mFastCallBase = BC_REG_FPARAMS_END - BC_REG_FPARAMS;
|
proc->mFastCallBase = BC_REG_FPARAMS_END - BC_REG_FPARAMS;
|
||||||
|
|
||||||
if (dec->mBase->mBase->mType != DT_TYPE_VOID && dec->mBase->mBase->mType != DT_TYPE_STRUCT)
|
if (dec->mBase->mBase->mType != DT_TYPE_VOID && dec->mBase->mBase->mType != DT_TYPE_STRUCT)
|
||||||
|
{
|
||||||
proc->mValueReturn = true;
|
proc->mValueReturn = true;
|
||||||
|
proc->mReturnType = InterTypeOf(dec->mBase->mBase);
|
||||||
|
}
|
||||||
|
|
||||||
InterCodeBasicBlock* entryBlock = new InterCodeBasicBlock(proc);
|
InterCodeBasicBlock* entryBlock = new InterCodeBasicBlock(proc);
|
||||||
|
|
||||||
|
|
|
@ -40370,7 +40370,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
{
|
{
|
||||||
mInterProc = proc;
|
mInterProc = proc;
|
||||||
|
|
||||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "test_find");
|
CheckFunc = !strcmp(mInterProc->mIdent->mString, "getchar");
|
||||||
|
|
||||||
int nblocks = proc->mBlocks.Size();
|
int nblocks = proc->mBlocks.Size();
|
||||||
tblocks = new NativeCodeBasicBlock * [nblocks];
|
tblocks = new NativeCodeBasicBlock * [nblocks];
|
||||||
|
@ -40425,7 +40425,25 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
|
|
||||||
// Place a temporary RTS
|
// Place a temporary RTS
|
||||||
|
|
||||||
mExitBlock->mIns.Push(NativeCodeInstruction(nullptr, ASMIT_RTS, ASMIM_IMPLIED, 0, nullptr, 0));
|
uint32 rflags = 0;
|
||||||
|
switch (proc->mReturnType)
|
||||||
|
{
|
||||||
|
case IT_BOOL:
|
||||||
|
case IT_INT8:
|
||||||
|
rflags = NCIF_LOWER;
|
||||||
|
break;
|
||||||
|
case IT_INT16:
|
||||||
|
case IT_POINTER:
|
||||||
|
rflags = NCIF_LOWER | NCIF_UPPER;
|
||||||
|
break;
|
||||||
|
case IT_INT32:
|
||||||
|
case IT_FLOAT:
|
||||||
|
rflags = NCIF_LOWER | NCIF_UPPER | NCIF_LONG;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
mExitBlock->mIns.Push(NativeCodeInstruction(nullptr, ASMIT_RTS, ASMIM_IMPLIED, 0, nullptr, rflags));
|
||||||
|
|
||||||
mEntryBlock->mTrueJump = CompileBlock(mInterProc, mInterProc->mBlocks[0]);
|
mEntryBlock->mTrueJump = CompileBlock(mInterProc, mInterProc->mBlocks[0]);
|
||||||
mEntryBlock->mBranch = ASMIT_JMP;
|
mEntryBlock->mBranch = ASMIT_JMP;
|
||||||
|
@ -40443,7 +40461,6 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if 1
|
#if 1
|
||||||
if (mExitBlock->mIns[0].mFlags == NCIF_LOWER)
|
|
||||||
if (mExitBlock->mIns[0].mFlags == NCIF_LOWER)
|
if (mExitBlock->mIns[0].mFlags == NCIF_LOWER)
|
||||||
{
|
{
|
||||||
mExitBlock->mIns[0].mFlags = 0;
|
mExitBlock->mIns[0].mFlags = 0;
|
||||||
|
@ -41021,6 +41038,8 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
mEntryBlock->ReplaceFinalZeroPageUse(this);
|
mEntryBlock->ReplaceFinalZeroPageUse(this);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int t = 0;
|
int t = 0;
|
||||||
#if 1
|
#if 1
|
||||||
do
|
do
|
||||||
|
@ -41029,8 +41048,8 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
|
|
||||||
BuildDataFlowSets();
|
BuildDataFlowSets();
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
changed = mEntryBlock->RemoveUnusedResultInstructions();
|
|
||||||
|
|
||||||
|
changed = mEntryBlock->RemoveUnusedResultInstructions();
|
||||||
|
|
||||||
if (step == 0)
|
if (step == 0)
|
||||||
{
|
{
|
||||||
|
@ -41646,8 +41665,10 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
else
|
else
|
||||||
cnt++;
|
cnt++;
|
||||||
|
|
||||||
|
|
||||||
} while (changed);
|
} while (changed);
|
||||||
|
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->ReduceLocalYPressure();
|
mEntryBlock->ReduceLocalYPressure();
|
||||||
|
|
|
@ -28,8 +28,52 @@ Parser::~Parser(void)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Declaration* Parser::FindBaseMemberFunction(Declaration* dec, Declaration* mdec)
|
||||||
|
{
|
||||||
|
const Ident* ident = mdec->mIdent;
|
||||||
|
|
||||||
|
if (ident->mString[0] == '~')
|
||||||
|
{
|
||||||
|
// this is the destructor, need special search
|
||||||
|
|
||||||
|
Declaration * pdec = dec;
|
||||||
|
Declaration * pmdec = nullptr;
|
||||||
|
|
||||||
|
while (pdec->mBase && !pmdec)
|
||||||
|
{
|
||||||
|
pdec = pdec->mBase->mBase;
|
||||||
|
pmdec = pdec->mScope->Lookup(pdec->mIdent->PreMangle("~"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return pmdec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Declaration * pdec = dec;
|
||||||
|
Declaration * pmdec = nullptr;
|
||||||
|
|
||||||
|
while (pdec->mBase && !pmdec)
|
||||||
|
{
|
||||||
|
pdec = pdec->mBase->mBase;
|
||||||
|
pmdec = pdec->mScope->Lookup(ident);
|
||||||
|
|
||||||
|
while (pmdec && !mdec->mBase->IsDerivedFrom(pmdec->mBase))
|
||||||
|
pmdec = pmdec->mNext;
|
||||||
|
|
||||||
|
if (pmdec)
|
||||||
|
return pmdec;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pmdec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Parser::AddMemberFunction(Declaration* dec, Declaration* mdec)
|
void Parser::AddMemberFunction(Declaration* dec, Declaration* mdec)
|
||||||
{
|
{
|
||||||
|
Declaration* pmdec = FindBaseMemberFunction(dec, mdec);
|
||||||
|
if (pmdec)
|
||||||
|
mdec->mBase->mFlags |= pmdec->mBase->mFlags & DTF_VIRTUAL;
|
||||||
|
|
||||||
Declaration* gdec = mCompilationUnits->mScope->Insert(mdec->mQualIdent, mdec);
|
Declaration* gdec = mCompilationUnits->mScope->Insert(mdec->mQualIdent, mdec);
|
||||||
if (gdec)
|
if (gdec)
|
||||||
{
|
{
|
||||||
|
@ -50,6 +94,7 @@ void Parser::AddMemberFunction(Declaration* dec, Declaration* mdec)
|
||||||
dec->mScope->Insert(mdec->mIdent, gdec);
|
dec->mScope->Insert(mdec->mIdent, gdec);
|
||||||
if (dec->mConst)
|
if (dec->mConst)
|
||||||
dec->mConst->mScope->Insert(mdec->mIdent, gdec);
|
dec->mConst->mScope->Insert(mdec->mIdent, gdec);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
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);
|
||||||
|
@ -341,7 +386,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
|
||||||
|
|
||||||
Declaration* vmpdec = nullptr;
|
Declaration* vmpdec = nullptr;
|
||||||
|
|
||||||
while (vmdec && vmdec->mBase->IsSame(mdec->mBase))
|
while (vmdec && !mdec->mBase->IsDerivedFrom(vmdec->mBase))
|
||||||
{
|
{
|
||||||
vmpdec = vmdec;
|
vmpdec = vmdec;
|
||||||
vmdec = vmdec->mNext;
|
vmdec = vmdec->mNext;
|
||||||
|
@ -3162,6 +3207,48 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
||||||
|
|
||||||
return cdec;
|
return cdec;
|
||||||
}
|
}
|
||||||
|
if ((mCompilerOptions & COPT_CPLUSPLUS) && pthis && mScanner->mToken == TK_OPERATOR)
|
||||||
|
{
|
||||||
|
mScanner->NextToken();
|
||||||
|
bdec = ParseBaseTypeDeclaration(typeFlags, false);
|
||||||
|
|
||||||
|
Declaration* ctdec = ParseFunctionDeclaration(bdec);
|
||||||
|
|
||||||
|
if (ctdec->mParams)
|
||||||
|
mErrors->Error(ctdec->mLocation, EERR_WRONG_PARAMETER, "Cast operators can't have parameter");
|
||||||
|
|
||||||
|
PrependThisArgument(ctdec, pthis);
|
||||||
|
|
||||||
|
Declaration* cdec = new Declaration(ctdec->mLocation, DT_CONST_FUNCTION);
|
||||||
|
cdec->mBase = ctdec;
|
||||||
|
|
||||||
|
cdec->mFlags |= cdec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE);
|
||||||
|
ctdec->mFlags |= storageFlags & DTF_VIRTUAL;
|
||||||
|
|
||||||
|
cdec->mSection = mCodeSection;
|
||||||
|
cdec->mBase->mFlags |= typeFlags;
|
||||||
|
|
||||||
|
if (mCompilerOptions & COPT_NATIVE)
|
||||||
|
cdec->mFlags |= DTF_NATIVE;
|
||||||
|
|
||||||
|
cdec->mIdent = Ident::Unique("(cast)");
|
||||||
|
cdec->mQualIdent = pthis->mBase->mScope->Mangle(cdec->mIdent);
|
||||||
|
|
||||||
|
if (mScanner->mToken == TK_OPEN_BRACE)
|
||||||
|
{
|
||||||
|
cdec->mCompilerOptions = mCompilerOptions;
|
||||||
|
cdec->mBase->mCompilerOptions = mCompilerOptions;
|
||||||
|
|
||||||
|
cdec->mVarIndex = -1;
|
||||||
|
|
||||||
|
cdec->mValue = ParseFunction(cdec->mBase);
|
||||||
|
|
||||||
|
cdec->mFlags |= DTF_DEFINED | DTF_REQUEST_INLINE;
|
||||||
|
cdec->mNumVars = mLocalIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cdec;
|
||||||
|
}
|
||||||
|
|
||||||
bdec = ParseBaseTypeDeclaration(typeFlags, false);
|
bdec = ParseBaseTypeDeclaration(typeFlags, false);
|
||||||
}
|
}
|
||||||
|
@ -3366,6 +3453,46 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
||||||
|
|
||||||
return bdec->mDestructor;
|
return bdec->mDestructor;
|
||||||
}
|
}
|
||||||
|
else if (ConsumeTokenIf(TK_OPERATOR))
|
||||||
|
{
|
||||||
|
Declaration* tdec = ParseBaseTypeDeclaration(0, true);
|
||||||
|
|
||||||
|
Declaration* ctdec = ParseFunctionDeclaration(tdec);
|
||||||
|
|
||||||
|
if (ctdec->mParams)
|
||||||
|
mErrors->Error(ctdec->mLocation, EERR_WRONG_PARAMETER, "Cast operators can't have parameter");
|
||||||
|
|
||||||
|
Declaration* bthis = new Declaration(mScanner->mLocation, DT_TYPE_POINTER);
|
||||||
|
bthis->mFlags |= DTF_CONST | DTF_DEFINED;
|
||||||
|
if (ConsumeTokenIf(TK_CONST))
|
||||||
|
bthis->mBase = bdec->ToConstType();
|
||||||
|
else
|
||||||
|
bthis->mBase = bdec;
|
||||||
|
bthis->mSize = 2;
|
||||||
|
|
||||||
|
PrependThisArgument(ctdec, bthis);
|
||||||
|
|
||||||
|
Declaration* fdec = bdec->mScope->Lookup(Ident::Unique("(cast)"));
|
||||||
|
while (fdec && !fdec->mBase->IsSame(ctdec))
|
||||||
|
fdec = fdec->mNext;
|
||||||
|
|
||||||
|
if (fdec)
|
||||||
|
{
|
||||||
|
fdec->mCompilerOptions = mCompilerOptions;
|
||||||
|
fdec->mBase->mCompilerOptions = mCompilerOptions;
|
||||||
|
|
||||||
|
fdec->mVarIndex = -1;
|
||||||
|
|
||||||
|
fdec->mValue = ParseFunction(fdec->mBase);
|
||||||
|
|
||||||
|
fdec->mFlags |= DTF_DEFINED;
|
||||||
|
fdec->mNumVars = mLocalIndex;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mErrors->Error(ctdec->mLocation, EERR_DUPLICATE_DEFINITION, "Cast operator not declared", tdec->mIdent);
|
||||||
|
|
||||||
|
return fdec;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4536,7 +4663,10 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
|
||||||
int ncast = 0;
|
int ncast = 0;
|
||||||
Declaration* ext = ex->mDecType;
|
Declaration* ext = ex->mDecType;
|
||||||
while (ext && !ext->IsConstSame(ptype->mBase))
|
while (ext && !ext->IsConstSame(ptype->mBase))
|
||||||
|
{
|
||||||
|
ncast++;
|
||||||
ext = ext->mBase;
|
ext = ext->mBase;
|
||||||
|
}
|
||||||
|
|
||||||
if (ext)
|
if (ext)
|
||||||
{
|
{
|
||||||
|
@ -4548,12 +4678,19 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
|
||||||
else
|
else
|
||||||
return NOOVERLOAD;
|
return NOOVERLOAD;
|
||||||
}
|
}
|
||||||
else if (ptype->mType == DT_TYPE_POINTER && etype->mType == DT_TYPE_ARRAY && ptype->mBase->IsSameMutable(etype->mBase))
|
else if (ptype->mType == DT_TYPE_POINTER && (etype->mType == DT_TYPE_ARRAY || etype->mType == DT_TYPE_POINTER) && ptype->mBase->IsSameMutable(etype->mBase))
|
||||||
dist += 1;
|
dist += 1;
|
||||||
else if (ptype->mType == DT_TYPE_POINTER && etype->mType == DT_TYPE_FUNCTION && ptype->mBase->IsSame(etype))
|
else if (ptype->mType == DT_TYPE_POINTER && etype->mType == DT_TYPE_FUNCTION && ptype->mBase->IsSame(etype))
|
||||||
dist += 0;
|
dist += 0;
|
||||||
else if (ptype->IsSubType(etype))
|
else if (ptype->IsSubType(etype))
|
||||||
dist += 256;
|
dist += 256;
|
||||||
|
else if (ptype->mType == DT_TYPE_REFERENCE && ptype->mBase->IsSame(etype))
|
||||||
|
{
|
||||||
|
if (ex->mType == EX_VARIABLE)
|
||||||
|
dist += 1;
|
||||||
|
else
|
||||||
|
return NOOVERLOAD;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return NOOVERLOAD;
|
return NOOVERLOAD;
|
||||||
|
|
||||||
|
@ -4574,6 +4711,41 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
|
||||||
return dist;
|
return dist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Expression* Parser::CoerceExpression(Expression* exp, Declaration* type)
|
||||||
|
{
|
||||||
|
Declaration* tdec = exp->mDecType;
|
||||||
|
while (tdec->mType == DT_TYPE_REFERENCE)
|
||||||
|
tdec = tdec->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)
|
||||||
|
{
|
||||||
|
Expression* aexp = new Expression(exp->mLocation, EX_PREFIX);
|
||||||
|
aexp->mToken = TK_BINARY_AND;
|
||||||
|
aexp->mDecType = tdec->BuildPointer(exp->mLocation);
|
||||||
|
aexp->mLeft = exp;
|
||||||
|
|
||||||
|
Expression* nexp = new Expression(exp->mLocation, EX_CALL);
|
||||||
|
nexp->mLeft = new Expression(exp->mLocation, EX_CONSTANT);
|
||||||
|
nexp->mLeft->mDecType = fexp->mBase;
|
||||||
|
nexp->mLeft->mDecValue = fexp;
|
||||||
|
nexp->mRight = aexp;
|
||||||
|
|
||||||
|
return nexp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return exp;
|
||||||
|
}
|
||||||
|
|
||||||
Expression * Parser::ResolveOverloadCall(Expression* exp, Expression* exp2)
|
Expression * Parser::ResolveOverloadCall(Expression* exp, Expression* exp2)
|
||||||
{
|
{
|
||||||
if (exp->mType == EX_CALL && exp->mLeft->mDecValue)
|
if (exp->mType == EX_CALL && exp->mLeft->mDecValue)
|
||||||
|
@ -4647,7 +4819,7 @@ Expression* Parser::ParsePostfixExpression(bool lhs)
|
||||||
nexp->mRight = ParseExpression(false);
|
nexp->mRight = ParseExpression(false);
|
||||||
ConsumeToken(TK_CLOSE_BRACKET);
|
ConsumeToken(TK_CLOSE_BRACKET);
|
||||||
|
|
||||||
if (exp->mDecType->mType == DT_TYPE_STRUCT)
|
if (exp->mDecType->mType == DT_TYPE_STRUCT || exp->mDecType->mType == DT_TYPE_REFERENCE && exp->mDecType->mBase->mType == DT_TYPE_STRUCT)
|
||||||
{
|
{
|
||||||
nexp = CheckOperatorOverload(nexp);
|
nexp = CheckOperatorOverload(nexp);
|
||||||
}
|
}
|
||||||
|
@ -4899,6 +5071,8 @@ Expression* Parser::ParsePrefixExpression(bool lhs)
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
nexp = ParsePrefixExpression(false);
|
nexp = ParsePrefixExpression(false);
|
||||||
nexp = nexp->LogicInvertExpression();
|
nexp = nexp->LogicInvertExpression();
|
||||||
|
nexp = CheckOperatorOverload(nexp);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (mScanner->mToken == TK_INC || mScanner->mToken == TK_DEC)
|
else if (mScanner->mToken == TK_INC || mScanner->mToken == TK_DEC)
|
||||||
{
|
{
|
||||||
|
@ -5403,9 +5577,9 @@ Expression* Parser::ParseLogicAndExpression(bool lhs)
|
||||||
{
|
{
|
||||||
Expression* nexp = new Expression(mScanner->mLocation, EX_LOGICAL_AND);
|
Expression* nexp = new Expression(mScanner->mLocation, EX_LOGICAL_AND);
|
||||||
nexp->mToken = mScanner->mToken;
|
nexp->mToken = mScanner->mToken;
|
||||||
nexp->mLeft = exp;
|
nexp->mLeft = CoerceExpression(exp, TheBoolTypeDeclaration);
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
nexp->mRight = ParseBinaryOrExpression(false);
|
nexp->mRight = CoerceExpression(ParseBinaryOrExpression(false), TheBoolTypeDeclaration);
|
||||||
nexp->mDecType = TheBoolTypeDeclaration;
|
nexp->mDecType = TheBoolTypeDeclaration;
|
||||||
exp = nexp->ConstantFold(mErrors);
|
exp = nexp->ConstantFold(mErrors);
|
||||||
}
|
}
|
||||||
|
@ -5421,9 +5595,9 @@ Expression* Parser::ParseLogicOrExpression(bool lhs)
|
||||||
{
|
{
|
||||||
Expression* nexp = new Expression(mScanner->mLocation, EX_LOGICAL_OR);
|
Expression* nexp = new Expression(mScanner->mLocation, EX_LOGICAL_OR);
|
||||||
nexp->mToken = mScanner->mToken;
|
nexp->mToken = mScanner->mToken;
|
||||||
nexp->mLeft = exp;
|
nexp->mLeft = CoerceExpression(exp, TheBoolTypeDeclaration);
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
nexp->mRight = ParseLogicAndExpression(false);
|
nexp->mRight = CoerceExpression(ParseLogicAndExpression(false), TheBoolTypeDeclaration);
|
||||||
nexp->mDecType = TheBoolTypeDeclaration;
|
nexp->mDecType = TheBoolTypeDeclaration;
|
||||||
exp = nexp->ConstantFold(mErrors);
|
exp = nexp->ConstantFold(mErrors);
|
||||||
}
|
}
|
||||||
|
@ -5438,7 +5612,7 @@ Expression* Parser::ParseConditionalExpression(bool lhs)
|
||||||
if (mScanner->mToken == TK_QUESTIONMARK)
|
if (mScanner->mToken == TK_QUESTIONMARK)
|
||||||
{
|
{
|
||||||
Expression* nexp = new Expression(mScanner->mLocation, EX_CONDITIONAL);
|
Expression* nexp = new Expression(mScanner->mLocation, EX_CONDITIONAL);
|
||||||
nexp->mLeft = exp;
|
nexp->mLeft = CoerceExpression(exp, TheBoolTypeDeclaration);
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
Expression* texp = new Expression(mScanner->mLocation, EX_SEQUENCE);
|
Expression* texp = new Expression(mScanner->mLocation, EX_SEQUENCE);
|
||||||
nexp->mRight = texp;
|
nexp->mRight = texp;
|
||||||
|
@ -5578,6 +5752,9 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
|
||||||
else if (exp->mType == EX_INDEX)
|
else if (exp->mType == EX_INDEX)
|
||||||
{
|
{
|
||||||
Declaration* tdec = exp->mLeft->mDecType;
|
Declaration* tdec = exp->mLeft->mDecType;
|
||||||
|
while (tdec->mType == DT_TYPE_REFERENCE)
|
||||||
|
tdec = tdec->mBase;
|
||||||
|
|
||||||
if (tdec->mType == DT_TYPE_STRUCT)
|
if (tdec->mType == DT_TYPE_STRUCT)
|
||||||
{
|
{
|
||||||
const Ident* opident = Ident::Unique("operator[]");
|
const Ident* opident = Ident::Unique("operator[]");
|
||||||
|
@ -5599,7 +5776,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
|
||||||
texp->mLeft = exp->mLeft;
|
texp->mLeft = exp->mLeft;
|
||||||
texp->mDecType = new Declaration(nexp->mLocation, DT_TYPE_POINTER);
|
texp->mDecType = new Declaration(nexp->mLocation, DT_TYPE_POINTER);
|
||||||
texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
||||||
texp->mDecType->mBase = exp->mLeft->mDecType;
|
texp->mDecType->mBase = tdec;
|
||||||
texp->mDecType->mSize = 2;
|
texp->mDecType->mSize = 2;
|
||||||
|
|
||||||
Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
|
Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
|
||||||
|
@ -5851,6 +6028,9 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
|
||||||
if (opident)
|
if (opident)
|
||||||
{
|
{
|
||||||
Declaration* tdec = exp->mLeft->mDecType;
|
Declaration* tdec = exp->mLeft->mDecType;
|
||||||
|
while (tdec->mType == DT_TYPE_REFERENCE)
|
||||||
|
tdec = tdec->mBase;
|
||||||
|
|
||||||
if (tdec->mType == DT_TYPE_STRUCT)
|
if (tdec->mType == DT_TYPE_STRUCT)
|
||||||
{
|
{
|
||||||
Declaration* mdec = tdec->mScope->Lookup(opident);
|
Declaration* mdec = tdec->mScope->Lookup(opident);
|
||||||
|
@ -5870,7 +6050,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
|
||||||
texp->mLeft = exp->mLeft;
|
texp->mLeft = exp->mLeft;
|
||||||
texp->mDecType = new Declaration(nexp->mLocation, DT_TYPE_POINTER);
|
texp->mDecType = new Declaration(nexp->mLocation, DT_TYPE_POINTER);
|
||||||
texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
||||||
texp->mDecType->mBase = exp->mLeft->mDecType;
|
texp->mDecType->mBase = tdec;
|
||||||
texp->mDecType->mSize = 2;
|
texp->mDecType->mSize = 2;
|
||||||
|
|
||||||
nexp->mRight = texp;
|
nexp->mRight = texp;
|
||||||
|
@ -5883,6 +6063,44 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (exp->mType == EX_LOGICAL_NOT)
|
||||||
|
{
|
||||||
|
const Ident* opident = Ident::Unique("operator!");
|
||||||
|
Declaration* tdec = exp->mLeft->mDecType;
|
||||||
|
while (tdec->mType == DT_TYPE_REFERENCE)
|
||||||
|
tdec = tdec->mBase;
|
||||||
|
|
||||||
|
if (tdec->mType == DT_TYPE_STRUCT)
|
||||||
|
{
|
||||||
|
Declaration* mdec = tdec->mScope->Lookup(opident);
|
||||||
|
if (mdec)
|
||||||
|
{
|
||||||
|
Expression* nexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
|
|
||||||
|
nexp->mLeft = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
|
nexp->mLeft->mDecType = mdec->mBase;
|
||||||
|
nexp->mLeft->mDecValue = mdec;
|
||||||
|
|
||||||
|
nexp->mDecType = mdec->mBase;
|
||||||
|
nexp->mRight = exp->mRight;
|
||||||
|
|
||||||
|
Expression* texp = new Expression(nexp->mLocation, EX_PREFIX);
|
||||||
|
texp->mToken = TK_BINARY_AND;
|
||||||
|
texp->mLeft = exp->mLeft;
|
||||||
|
texp->mDecType = new Declaration(nexp->mLocation, DT_TYPE_POINTER);
|
||||||
|
texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
||||||
|
texp->mDecType->mBase = tdec;
|
||||||
|
texp->mDecType->mSize = 2;
|
||||||
|
|
||||||
|
nexp->mRight = texp;
|
||||||
|
|
||||||
|
nexp = ResolveOverloadCall(nexp);
|
||||||
|
nexp->mDecType = nexp->mLeft->mDecType->mBase;
|
||||||
|
|
||||||
|
exp = nexp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return exp;
|
return exp;
|
||||||
|
@ -6080,7 +6298,7 @@ Expression* Parser::ParseStatement(void)
|
||||||
case TK_IF:
|
case TK_IF:
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
exp = new Expression(mScanner->mLocation, EX_IF);
|
exp = new Expression(mScanner->mLocation, EX_IF);
|
||||||
exp->mLeft = CleanupExpression(ParseParenthesisExpression());
|
exp->mLeft = CoerceExpression(CleanupExpression(ParseParenthesisExpression()), TheBoolTypeDeclaration);
|
||||||
exp->mRight = new Expression(mScanner->mLocation, EX_ELSE);
|
exp->mRight = new Expression(mScanner->mLocation, EX_ELSE);
|
||||||
exp->mRight->mLeft = ParseStatement();
|
exp->mRight->mLeft = ParseStatement();
|
||||||
if (mScanner->mToken == TK_ELSE)
|
if (mScanner->mToken == TK_ELSE)
|
||||||
|
@ -6099,7 +6317,7 @@ Expression* Parser::ParseStatement(void)
|
||||||
mScope = scope;
|
mScope = scope;
|
||||||
|
|
||||||
exp = new Expression(mScanner->mLocation, EX_WHILE);
|
exp = new Expression(mScanner->mLocation, EX_WHILE);
|
||||||
exp->mLeft = CleanupExpression(ParseParenthesisExpression());
|
exp->mLeft = CoerceExpression(CleanupExpression(ParseParenthesisExpression()), TheBoolTypeDeclaration);
|
||||||
exp->mRight = ParseStatement();
|
exp->mRight = ParseStatement();
|
||||||
|
|
||||||
mScope->End(mScanner->mLocation);
|
mScope->End(mScanner->mLocation);
|
||||||
|
@ -6113,7 +6331,7 @@ Expression* Parser::ParseStatement(void)
|
||||||
if (mScanner->mToken == TK_WHILE)
|
if (mScanner->mToken == TK_WHILE)
|
||||||
{
|
{
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
exp->mLeft = CleanupExpression(ParseParenthesisExpression());
|
exp->mLeft = CoerceExpression(CleanupExpression(ParseParenthesisExpression()), TheBoolTypeDeclaration);
|
||||||
ConsumeToken(TK_SEMICOLON);
|
ConsumeToken(TK_SEMICOLON);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -6147,7 +6365,7 @@ Expression* Parser::ParseStatement(void)
|
||||||
|
|
||||||
// Condition
|
// Condition
|
||||||
if (mScanner->mToken != TK_SEMICOLON)
|
if (mScanner->mToken != TK_SEMICOLON)
|
||||||
conditionExp = CleanupExpression(ParseExpression(false));
|
conditionExp = CoerceExpression(CleanupExpression(ParseExpression(false)), TheBoolTypeDeclaration);
|
||||||
|
|
||||||
if (mScanner->mToken == TK_SEMICOLON)
|
if (mScanner->mToken == TK_SEMICOLON)
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
|
|
|
@ -50,6 +50,7 @@ protected:
|
||||||
|
|
||||||
void ParseVariableInit(Declaration* ndec);
|
void ParseVariableInit(Declaration* ndec);
|
||||||
void AddMemberFunction(Declaration* dec, Declaration* mdec);
|
void AddMemberFunction(Declaration* dec, Declaration* mdec);
|
||||||
|
Declaration* FindBaseMemberFunction(Declaration* dec, Declaration* mdec);
|
||||||
|
|
||||||
Expression * AddFunctionCallRefReturned(Expression * exp);
|
Expression * AddFunctionCallRefReturned(Expression * exp);
|
||||||
Expression* CleanupExpression(Expression* exp);
|
Expression* CleanupExpression(Expression* exp);
|
||||||
|
@ -88,6 +89,7 @@ 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* ParseSimpleExpression(bool lhs);
|
Expression* ParseSimpleExpression(bool lhs);
|
||||||
Expression* ParsePrefixExpression(bool lhs);
|
Expression* ParsePrefixExpression(bool lhs);
|
||||||
|
|
|
@ -161,6 +161,7 @@ const char* TokenNames[] =
|
||||||
"'new'",
|
"'new'",
|
||||||
"'delete'",
|
"'delete'",
|
||||||
"'virtual'",
|
"'virtual'",
|
||||||
|
"'operator'",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -321,6 +322,7 @@ Scanner::Scanner(Errors* errors, Preprocessor* preprocessor)
|
||||||
mDefines = new MacroDict();
|
mDefines = new MacroDict();
|
||||||
mDefineArguments = nullptr;
|
mDefineArguments = nullptr;
|
||||||
mToken = TK_NONE;
|
mToken = TK_NONE;
|
||||||
|
mUngetToken = TK_NONE;
|
||||||
|
|
||||||
NextChar();
|
NextChar();
|
||||||
|
|
||||||
|
@ -873,7 +875,12 @@ void Scanner::NextToken(void)
|
||||||
|
|
||||||
void Scanner::NextRawToken(void)
|
void Scanner::NextRawToken(void)
|
||||||
{
|
{
|
||||||
if (mToken != TK_EOF)
|
if (mUngetToken)
|
||||||
|
{
|
||||||
|
mToken = mUngetToken;
|
||||||
|
mUngetToken = TK_NONE;
|
||||||
|
}
|
||||||
|
else if (mToken != TK_EOF)
|
||||||
{
|
{
|
||||||
mToken = TK_ERROR;
|
mToken = TK_ERROR;
|
||||||
|
|
||||||
|
@ -1480,6 +1487,9 @@ void Scanner::NextRawToken(void)
|
||||||
case TK_BINARY_XOR:
|
case TK_BINARY_XOR:
|
||||||
mTokenIdent = Ident::Unique("operator^");
|
mTokenIdent = Ident::Unique("operator^");
|
||||||
break;
|
break;
|
||||||
|
case TK_LOGICAL_NOT:
|
||||||
|
mTokenIdent = Ident::Unique("operator!");
|
||||||
|
break;
|
||||||
|
|
||||||
case TK_LEFT_SHIFT:
|
case TK_LEFT_SHIFT:
|
||||||
mTokenIdent = Ident::Unique("operator<<");
|
mTokenIdent = Ident::Unique("operator<<");
|
||||||
|
@ -1522,7 +1532,11 @@ void Scanner::NextRawToken(void)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
mErrors->Error(mLocation, EERR_INVALID_OPERATOR, "Invalid operator token");
|
// dirty little hack to implement token preview, got to fix
|
||||||
|
// this with an infinit preview sequence at one point
|
||||||
|
mUngetToken = mToken;
|
||||||
|
mToken = TK_OPERATOR;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mToken = TK_IDENT;
|
mToken = TK_IDENT;
|
||||||
|
|
|
@ -160,6 +160,7 @@ enum Token
|
||||||
TK_NEW,
|
TK_NEW,
|
||||||
TK_DELETE,
|
TK_DELETE,
|
||||||
TK_VIRTUAL,
|
TK_VIRTUAL,
|
||||||
|
TK_OPERATOR,
|
||||||
|
|
||||||
NUM_TOKENS
|
NUM_TOKENS
|
||||||
};
|
};
|
||||||
|
@ -260,6 +261,8 @@ protected:
|
||||||
|
|
||||||
MacroDict* mDefines, * mDefineArguments;
|
MacroDict* mDefines, * mDefineArguments;
|
||||||
|
|
||||||
|
Token mUngetToken;
|
||||||
|
|
||||||
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