Add template algorithm sort
This commit is contained in:
parent
ae2fbb6256
commit
50cc2afb52
|
@ -0,0 +1,37 @@
|
||||||
|
#ifndef OPP_ALGORITHM_H
|
||||||
|
#define OPP_ALGORITHM_H
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline void swap(T & x, T & y)
|
||||||
|
{
|
||||||
|
T t(x); x = y; y = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class LT>
|
||||||
|
void sort(T s, T e)
|
||||||
|
{
|
||||||
|
while (s != e)
|
||||||
|
{
|
||||||
|
auto p = s;
|
||||||
|
auto q = s;
|
||||||
|
|
||||||
|
q++;
|
||||||
|
while (q != e)
|
||||||
|
{
|
||||||
|
if (LT(*q, *p))
|
||||||
|
{
|
||||||
|
swap(*q, *p);
|
||||||
|
p++;
|
||||||
|
swap(*q, *p);
|
||||||
|
}
|
||||||
|
q++;
|
||||||
|
}
|
||||||
|
|
||||||
|
sort<T, LT>(s, p);
|
||||||
|
p++;
|
||||||
|
s = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -16,6 +16,11 @@ static inline char sstrlen(const char * sp)
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void swap(string & u, string & v)
|
||||||
|
{
|
||||||
|
char * p = u.cstr; u.cstr = v.cstr; v.cstr = p;
|
||||||
|
}
|
||||||
|
|
||||||
string::string(void) : cstr(nullptr)
|
string::string(void) : cstr(nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@ class string
|
||||||
private:
|
private:
|
||||||
char * cstr;
|
char * cstr;
|
||||||
|
|
||||||
|
friend void swap(string & u, string & v);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
string(void);
|
string(void);
|
||||||
string(const string & s);
|
string(const string & s);
|
||||||
|
@ -70,6 +72,8 @@ protected:
|
||||||
string(char l, char * b);
|
string(char l, char * b);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void swap(string & u, string & v);
|
||||||
|
|
||||||
#pragma compile("string.cpp")
|
#pragma compile("string.cpp")
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -70,6 +70,36 @@ public:
|
||||||
return _data[at];
|
return _data[at];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
T * begin(void)
|
||||||
|
{
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T * begin(void) const
|
||||||
|
{
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T * cbegin(void) const
|
||||||
|
{
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
T * end(void)
|
||||||
|
{
|
||||||
|
return _data + _size;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T * end(void) const
|
||||||
|
{
|
||||||
|
return _data + _size;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T * cend(void) const
|
||||||
|
{
|
||||||
|
return _data + _size;
|
||||||
|
}
|
||||||
|
|
||||||
T & front(void)
|
T & front(void)
|
||||||
{
|
{
|
||||||
return _data[0];
|
return _data[0];
|
||||||
|
|
|
@ -842,7 +842,7 @@ Declaration::Declaration(const Location& loc, DecType type)
|
||||||
mDefaultConstructor(nullptr), mDestructor(nullptr), mCopyConstructor(nullptr), mCopyAssignment(nullptr),
|
mDefaultConstructor(nullptr), mDestructor(nullptr), mCopyConstructor(nullptr), mCopyAssignment(nullptr),
|
||||||
mVectorConstructor(nullptr), mVectorDestructor(nullptr), mVectorCopyConstructor(nullptr), mVectorCopyAssignment(nullptr),
|
mVectorConstructor(nullptr), mVectorDestructor(nullptr), mVectorCopyConstructor(nullptr), mVectorCopyAssignment(nullptr),
|
||||||
mVTable(nullptr), mTemplate(nullptr),
|
mVTable(nullptr), mTemplate(nullptr),
|
||||||
mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1),
|
mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1), mFriends(nullptr),
|
||||||
mInteger(0), mNumber(0), mMinValue(-0x80000000LL), mMaxValue(0x7fffffffLL), mFastCallBase(0), mFastCallSize(0), mStride(0), mStripe(1),
|
mInteger(0), mNumber(0), mMinValue(-0x80000000LL), mMaxValue(0x7fffffffLL), mFastCallBase(0), mFastCallSize(0), mStride(0), mStripe(1),
|
||||||
mCompilerOptions(0), mUseCount(0), mTokens(nullptr), mParser(nullptr)
|
mCompilerOptions(0), mUseCount(0), mTokens(nullptr), mParser(nullptr)
|
||||||
{}
|
{}
|
||||||
|
@ -947,6 +947,10 @@ const Ident* Declaration::MangleIdent(void)
|
||||||
sprintf_s(buffer, "%d", (int)mInteger);
|
sprintf_s(buffer, "%d", (int)mInteger);
|
||||||
mMangleIdent = Ident::Unique(buffer);
|
mMangleIdent = Ident::Unique(buffer);
|
||||||
}
|
}
|
||||||
|
else if (mType == DT_CONST_FUNCTION)
|
||||||
|
{
|
||||||
|
mMangleIdent = mQualIdent;
|
||||||
|
}
|
||||||
else if (mType == DT_TYPE_INTEGER)
|
else if (mType == DT_TYPE_INTEGER)
|
||||||
{
|
{
|
||||||
char buffer[20];
|
char buffer[20];
|
||||||
|
@ -1532,7 +1536,7 @@ bool Declaration::IsTemplateSameParams(const Declaration* dec, const Declaration
|
||||||
|
|
||||||
bool Declaration::IsSameParams(const Declaration* dec) const
|
bool Declaration::IsSameParams(const Declaration* dec) const
|
||||||
{
|
{
|
||||||
if (mType == DT_TYPE_FUNCTION && dec->mType == DT_TYPE_FUNCTION || mType == DT_TEMPLATE && dec->mType == DT_TEMPLATE)
|
if (mType == DT_TYPE_FUNCTION && dec->mType == DT_TYPE_FUNCTION)
|
||||||
{
|
{
|
||||||
Declaration* ld = mParams, * rd = dec->mParams;
|
Declaration* ld = mParams, * rd = dec->mParams;
|
||||||
while (ld && rd)
|
while (ld && rd)
|
||||||
|
@ -1545,6 +1549,24 @@ bool Declaration::IsSameParams(const Declaration* dec) const
|
||||||
|
|
||||||
return !ld && !rd;
|
return !ld && !rd;
|
||||||
}
|
}
|
||||||
|
else if (mType == DT_TEMPLATE && dec->mType == DT_TEMPLATE)
|
||||||
|
{
|
||||||
|
Declaration* ld = mParams, * rd = dec->mParams;
|
||||||
|
while (ld && rd)
|
||||||
|
{
|
||||||
|
if (ld->mType == DT_CONST_FUNCTION && rd->mType == DT_CONST_FUNCTION)
|
||||||
|
{
|
||||||
|
if (ld->mValue != rd->mValue)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (!ld->mBase->IsSame(rd->mBase))
|
||||||
|
return false;
|
||||||
|
ld = ld->mNext;
|
||||||
|
rd = rd->mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !ld && !rd;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -272,7 +272,7 @@ public:
|
||||||
TokenSequence * mTokens;
|
TokenSequence * mTokens;
|
||||||
Parser * mParser;
|
Parser * mParser;
|
||||||
|
|
||||||
GrowingArray<Declaration*> mCallers, mCalled;
|
GrowingArray<Declaration*> mCallers, mCalled, mFriends;
|
||||||
|
|
||||||
bool CanAssign(const Declaration* fromType) const;
|
bool CanAssign(const Declaration* fromType) const;
|
||||||
bool IsSame(const Declaration* dec) const;
|
bool IsSame(const Declaration* dec) const;
|
||||||
|
|
|
@ -162,6 +162,28 @@ InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* p
|
||||||
{
|
{
|
||||||
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign numeric value to pointer");
|
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign numeric value to pointer");
|
||||||
}
|
}
|
||||||
|
else if( type->mType == DT_TYPE_BOOL && v.mType->mType == DT_TYPE_POINTER)
|
||||||
|
{
|
||||||
|
InterInstruction* zins = new InterInstruction(exp->mLocation, IC_CONSTANT);
|
||||||
|
zins->mDst.mType = IT_POINTER;
|
||||||
|
zins->mDst.mTemp = proc->AddTemporary(IT_POINTER);
|
||||||
|
zins->mConst.mType = IT_POINTER;
|
||||||
|
zins->mConst.mMemory = IM_ABSOLUTE;
|
||||||
|
zins->mConst.mIntConst = 0;
|
||||||
|
block->Append(zins);
|
||||||
|
|
||||||
|
InterInstruction* cins = new InterInstruction(exp->mLocation, IC_RELATIONAL_OPERATOR);
|
||||||
|
cins->mOperator = IA_CMPNE;
|
||||||
|
cins->mSrc[0].mType = IT_POINTER;
|
||||||
|
cins->mSrc[0].mTemp = v.mTemp;
|
||||||
|
cins->mSrc[1].mType = IT_POINTER;
|
||||||
|
cins->mSrc[1].mTemp = zins->mDst.mTemp;
|
||||||
|
cins->mDst.mType = IT_BOOL;
|
||||||
|
cins->mDst.mTemp = proc->AddTemporary(IT_BOOL);
|
||||||
|
block->Append(cins);
|
||||||
|
v.mTemp = cins->mDst.mTemp;
|
||||||
|
v.mType = type;
|
||||||
|
}
|
||||||
else if (v.mType->mSize < type->mSize)
|
else if (v.mType->mSize < type->mSize)
|
||||||
{
|
{
|
||||||
if (v.mType->mSize == 1 && type->mSize == 2)
|
if (v.mType->mSize == 1 && type->mSize == 2)
|
||||||
|
@ -3697,6 +3719,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
if (!procType->mBase || procType->mBase->mType == DT_TYPE_VOID)
|
if (!procType->mBase || procType->mBase->mType == DT_TYPE_VOID)
|
||||||
mErrors->Error(exp->mLocation, EERR_INVALID_RETURN, "Function has void return type");
|
mErrors->Error(exp->mLocation, EERR_INVALID_RETURN, "Function has void return type");
|
||||||
|
else if (procType->mBase->mType == DT_TYPE_BOOL && (vr.mType->IsIntegerType() || vr.mType->mType == DT_TYPE_POINTER))
|
||||||
|
;
|
||||||
else if (!procType->mBase->CanAssign(vr.mType))
|
else if (!procType->mBase->CanAssign(vr.mType))
|
||||||
mErrors->Error(exp->mLocation, EERR_INVALID_RETURN, "Cannot return incompatible type");
|
mErrors->Error(exp->mLocation, EERR_INVALID_RETURN, "Cannot return incompatible type");
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ Parser::Parser(Errors* errors, Scanner* scanner, CompilationUnits* compilationUn
|
||||||
mInlineCall = false;
|
mInlineCall = false;
|
||||||
mCompilerOptionSP = 0;
|
mCompilerOptionSP = 0;
|
||||||
mThisPointer = nullptr;
|
mThisPointer = nullptr;
|
||||||
|
mFunction = nullptr;
|
||||||
|
|
||||||
for (int i = 0; i < 256; i++)
|
for (int i = 0; i < 256; i++)
|
||||||
mCharMap[i] = i;
|
mCharMap[i] = i;
|
||||||
|
@ -248,6 +249,13 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
|
||||||
flags |= DTF_PRIVATE | DTF_PROTECTED;
|
flags |= DTF_PRIVATE | DTF_PROTECTED;
|
||||||
ConsumeToken(TK_COLON);
|
ConsumeToken(TK_COLON);
|
||||||
}
|
}
|
||||||
|
else if (ConsumeTokenIf(TK_FRIEND))
|
||||||
|
{
|
||||||
|
mScope = oscope;
|
||||||
|
Declaration* fdec = ParseDeclaration(nullptr, true, false);
|
||||||
|
dec->mFriends.Push(fdec);
|
||||||
|
mScope = dec->mScope;
|
||||||
|
}
|
||||||
else if (ConsumeTokenIf(TK_CLOSE_BRACE))
|
else if (ConsumeTokenIf(TK_CLOSE_BRACE))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
@ -3210,7 +3218,7 @@ void Parser::ParseVariableInit(Declaration* ndec)
|
||||||
mErrors->Error(pexp->mLocation, EERR_INCOMPATIBLE_TYPES, "Can not initialize variable with expression", ndec->mIdent);
|
mErrors->Error(pexp->mLocation, EERR_INCOMPATIBLE_TYPES, "Can not initialize variable with expression", ndec->mIdent);
|
||||||
}
|
}
|
||||||
|
|
||||||
Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool expression, Declaration* pthis)
|
Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool expression, Declaration* pthis, Declaration* ptempl)
|
||||||
{
|
{
|
||||||
bool definingType = false, destructor = false;
|
bool definingType = false, destructor = false;
|
||||||
uint64 storageFlags = 0, typeFlags = 0;
|
uint64 storageFlags = 0, typeFlags = 0;
|
||||||
|
@ -3734,14 +3742,30 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ndec->mBase->mType == DT_TYPE_FUNCTION && pthis)
|
if (ptempl)
|
||||||
|
ptempl->mBase = ndec;
|
||||||
|
|
||||||
|
if (ptempl && mTemplateScope && ndec->mIdent)
|
||||||
{
|
{
|
||||||
if (ConsumeTokenIf(TK_CONST))
|
if (!strstr(ndec->mQualIdent->mString, mTemplateScope->mName->mString))
|
||||||
PrependThisArgument(ndec->mBase, pthis->mBase->ToConstType()->BuildConstPointer(ndec->mLocation));
|
{
|
||||||
else
|
ndec->mIdent = ndec->mIdent->Mangle(mTemplateScope->mName->mString);
|
||||||
PrependThisArgument(ndec->mBase, pthis);
|
ndec->mQualIdent = ndec->mQualIdent->Mangle(mTemplateScope->mName->mString);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ndec->mBase->mType == DT_TYPE_FUNCTION)
|
||||||
|
{
|
||||||
|
if (pthis)
|
||||||
|
{
|
||||||
|
if (ConsumeTokenIf(TK_CONST))
|
||||||
|
PrependThisArgument(ndec->mBase, pthis->mBase->ToConstType()->BuildConstPointer(ndec->mLocation));
|
||||||
|
else
|
||||||
|
PrependThisArgument(ndec->mBase, pthis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (variable)
|
if (variable)
|
||||||
{
|
{
|
||||||
ndec->mFlags |= storageFlags;
|
ndec->mFlags |= storageFlags;
|
||||||
|
@ -3776,11 +3800,15 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
||||||
if (ndec->mIdent == ndec->mQualIdent)
|
if (ndec->mIdent == ndec->mQualIdent)
|
||||||
{
|
{
|
||||||
Declaration* ldec = mScope->Insert(ndec->mIdent, pdec ? pdec : ndec);
|
Declaration* ldec = mScope->Insert(ndec->mIdent, pdec ? pdec : ndec);
|
||||||
|
#if 0
|
||||||
if (ldec && ldec->mTemplate && mTemplateScope)
|
if (ldec && ldec->mTemplate && mTemplateScope)
|
||||||
{
|
{
|
||||||
ndec->mQualIdent = ndec->mQualIdent->Mangle(mTemplateScope->mName->mString);
|
ndec->mQualIdent = ndec->mQualIdent->Mangle(mTemplateScope->mName->mString);
|
||||||
}
|
}
|
||||||
else if (ldec && ldec != pdec)
|
else
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ldec && ldec != pdec)
|
||||||
mErrors->Error(ndec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate definition");
|
mErrors->Error(ndec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate definition");
|
||||||
}
|
}
|
||||||
else if (!pdec)
|
else if (!pdec)
|
||||||
|
@ -4085,14 +4113,16 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
||||||
if (ndec->mBase->mType == DT_TYPE_FUNCTION)
|
if (ndec->mBase->mType == DT_TYPE_FUNCTION)
|
||||||
{
|
{
|
||||||
if (ndec->mFlags & DTF_DEFINED)
|
if (ndec->mFlags & DTF_DEFINED)
|
||||||
mErrors->Error(mScanner->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate function definition");
|
mErrors->Error(mScanner->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate function definition", ndec->mQualIdent);
|
||||||
|
|
||||||
ndec->mCompilerOptions = mCompilerOptions;
|
ndec->mCompilerOptions = mCompilerOptions;
|
||||||
ndec->mBase->mCompilerOptions = mCompilerOptions;
|
ndec->mBase->mCompilerOptions = mCompilerOptions;
|
||||||
|
|
||||||
ndec->mVarIndex = -1;
|
ndec->mVarIndex = -1;
|
||||||
|
|
||||||
|
mFunction = ndec;
|
||||||
ndec->mValue = ParseFunction(ndec->mBase);
|
ndec->mValue = ParseFunction(ndec->mBase);
|
||||||
|
mFunction = nullptr;
|
||||||
|
|
||||||
if (pthis)
|
if (pthis)
|
||||||
ndec->mFlags |= DTF_REQUEST_INLINE;
|
ndec->mFlags |= DTF_REQUEST_INLINE;
|
||||||
|
@ -4309,6 +4339,10 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
|
||||||
exp = new Expression(mScanner->mLocation, EX_TYPE);
|
exp = new Expression(mScanner->mLocation, EX_TYPE);
|
||||||
exp->mDecValue = nullptr;
|
exp->mDecValue = nullptr;
|
||||||
exp->mDecType = ParseBaseTypeDeclaration(0, true);
|
exp->mDecType = ParseBaseTypeDeclaration(0, true);
|
||||||
|
while (ConsumeTokenIf(TK_MUL))
|
||||||
|
exp->mDecType = exp->mDecType->BuildPointer(mScanner->mLocation);
|
||||||
|
while (ConsumeTokenIf(TK_BINARY_AND))
|
||||||
|
exp->mDecType = exp->mDecType->BuildReference(mScanner->mLocation);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TK_CONST:
|
case TK_CONST:
|
||||||
|
@ -4555,6 +4589,10 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
|
||||||
exp = new Expression(mScanner->mLocation, EX_TYPE);
|
exp = new Expression(mScanner->mLocation, EX_TYPE);
|
||||||
exp->mDecValue = nullptr;
|
exp->mDecValue = nullptr;
|
||||||
exp->mDecType = dec;
|
exp->mDecType = dec;
|
||||||
|
while (ConsumeTokenIf(TK_MUL))
|
||||||
|
exp->mDecType = exp->mDecType->BuildPointer(mScanner->mLocation);
|
||||||
|
while (ConsumeTokenIf(TK_BINARY_AND))
|
||||||
|
exp->mDecType = exp->mDecType->BuildReference(mScanner->mLocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (dec->mType == DT_ELEMENT)
|
else if (dec->mType == DT_ELEMENT)
|
||||||
|
@ -4737,7 +4775,12 @@ Expression* Parser::ParseQualify(Expression* exp)
|
||||||
if (tp && tp->mType == DT_ARGUMENT)
|
if (tp && tp->mType == DT_ARGUMENT)
|
||||||
tp = tp->mBase;
|
tp = tp->mBase;
|
||||||
if (!(tp && tp->mBase->IsConstSame(dtype)))
|
if (!(tp && tp->mBase->IsConstSame(dtype)))
|
||||||
mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Struct member identifier not visible", ident);
|
{
|
||||||
|
if (dtype->mFriends.Contains(mFunction))
|
||||||
|
;
|
||||||
|
else
|
||||||
|
mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Struct member identifier not visible", ident);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
|
@ -4952,7 +4995,13 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
|
||||||
else if (ptype->IsSame(ex->mDecType))
|
else if (ptype->IsSame(ex->mDecType))
|
||||||
;
|
;
|
||||||
else if (CanCoerceExpression(ex, ptype))
|
else if (CanCoerceExpression(ex, ptype))
|
||||||
|
{
|
||||||
dist += 512;
|
dist += 512;
|
||||||
|
if (ptype->mType == DT_TYPE_REFERENCE)
|
||||||
|
dist += 4;
|
||||||
|
else if (ptype->mType == DT_TYPE_RVALUEREF)
|
||||||
|
dist += 2;
|
||||||
|
}
|
||||||
else if (ptype->mType == DT_TYPE_REFERENCE && ptype->mBase->mType == DT_TYPE_STRUCT && etype->mType == DT_TYPE_STRUCT)
|
else if (ptype->mType == DT_TYPE_REFERENCE && ptype->mBase->mType == DT_TYPE_STRUCT && etype->mType == DT_TYPE_STRUCT)
|
||||||
{
|
{
|
||||||
if (ex->IsLValue())
|
if (ex->IsLValue())
|
||||||
|
@ -5247,7 +5296,9 @@ Expression * Parser::ResolveOverloadCall(Expression* exp, Expression* exp2)
|
||||||
while (fdec)
|
while (fdec)
|
||||||
{
|
{
|
||||||
int d = OverloadDistance(fdec, exp->mRight);
|
int d = OverloadDistance(fdec, exp->mRight);
|
||||||
if (d < ibest)
|
if (d == NOOVERLOAD)
|
||||||
|
;
|
||||||
|
else if (d < ibest)
|
||||||
{
|
{
|
||||||
dbest = fdec;
|
dbest = fdec;
|
||||||
pbest = exp->mRight;
|
pbest = exp->mRight;
|
||||||
|
@ -5262,7 +5313,9 @@ Expression * Parser::ResolveOverloadCall(Expression* exp, Expression* exp2)
|
||||||
while (fdec2)
|
while (fdec2)
|
||||||
{
|
{
|
||||||
int d = OverloadDistance(fdec2, exp2->mRight);
|
int d = OverloadDistance(fdec2, exp2->mRight);
|
||||||
if (d < ibest)
|
if (d == NOOVERLOAD)
|
||||||
|
;
|
||||||
|
else if (d < ibest)
|
||||||
{
|
{
|
||||||
dbest = fdec2;
|
dbest = fdec2;
|
||||||
pbest = exp2->mRight;
|
pbest = exp2->mRight;
|
||||||
|
@ -6244,6 +6297,9 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
|
||||||
if (exp->mType == EX_ASSIGNMENT)
|
if (exp->mType == EX_ASSIGNMENT)
|
||||||
{
|
{
|
||||||
Declaration* tdec = exp->mLeft->mDecType;
|
Declaration* tdec = exp->mLeft->mDecType;
|
||||||
|
while (tdec->mType == DT_TYPE_REFERENCE || tdec->mType == DT_TYPE_RVALUEREF)
|
||||||
|
tdec = tdec->mBase;
|
||||||
|
|
||||||
if (tdec->mType == DT_TYPE_STRUCT)
|
if (tdec->mType == DT_TYPE_STRUCT)
|
||||||
{
|
{
|
||||||
const Ident* opident = nullptr;
|
const Ident* opident = nullptr;
|
||||||
|
@ -6320,7 +6376,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->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);
|
||||||
|
@ -7138,7 +7194,10 @@ Expression* Parser::ParseStatement(void)
|
||||||
exp = new Expression(mScanner->mLocation, EX_RETURN);
|
exp = new Expression(mScanner->mLocation, EX_RETURN);
|
||||||
if (mScanner->mToken != TK_SEMICOLON)
|
if (mScanner->mToken != TK_SEMICOLON)
|
||||||
{
|
{
|
||||||
exp->mLeft = CleanupExpression(ParseRExpression());
|
exp->mLeft = ParseRExpression();
|
||||||
|
if (mReturnType)
|
||||||
|
exp->mLeft = CoerceExpression(exp->mLeft, mReturnType);
|
||||||
|
exp->mLeft = CleanupExpression(exp->mLeft);
|
||||||
if (exp->mLeft->mType == EX_CONSTRUCT && mReturnType && mReturnType->mType == DT_TYPE_STRUCT)
|
if (exp->mLeft->mType == EX_CONSTRUCT && mReturnType && mReturnType->mType == DT_TYPE_STRUCT)
|
||||||
{
|
{
|
||||||
Expression* cexp = exp->mLeft->mLeft->mLeft;
|
Expression* cexp = exp->mLeft->mLeft->mLeft;
|
||||||
|
@ -7325,8 +7384,13 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
||||||
{
|
{
|
||||||
if (exp->mType == EX_TYPE)
|
if (exp->mType == EX_TYPE)
|
||||||
epdec->mBase = exp->mDecType;
|
epdec->mBase = exp->mDecType;
|
||||||
|
else if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_FUNCTION)
|
||||||
|
epdec->mBase = exp->mDecValue;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
mErrors->Error(exp->mLocation, EERR_TEMPLATE_PARAMS, "Type parameter expected", pdec->mIdent);
|
mErrors->Error(exp->mLocation, EERR_TEMPLATE_PARAMS, "Type parameter expected", pdec->mIdent);
|
||||||
|
epdec->mBase = TheVoidTypeDeclaration;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -7367,14 +7431,13 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
||||||
p->mScanner->Replay(tmpld->mTokens);
|
p->mScanner->Replay(tmpld->mTokens);
|
||||||
|
|
||||||
tdec->mScope->mName = tdec->MangleIdent();
|
tdec->mScope->mName = tdec->MangleIdent();
|
||||||
|
|
||||||
p->mTemplateScope = tdec->mScope;
|
|
||||||
tdec->mBase = p->ParseDeclaration(nullptr, true, false);
|
|
||||||
p->mTemplateScope = nullptr;
|
|
||||||
|
|
||||||
tdec->mNext = tmpld->mNext;
|
tdec->mNext = tmpld->mNext;
|
||||||
tmpld->mNext = tdec;
|
tmpld->mNext = tdec;
|
||||||
|
|
||||||
|
p->mTemplateScope = tdec->mScope;
|
||||||
|
tdec->mBase = p->ParseDeclaration(nullptr, true, false, nullptr, tdec);
|
||||||
|
p->mTemplateScope = nullptr;
|
||||||
|
|
||||||
if (tdec->mBase->mType == DT_ANON)
|
if (tdec->mBase->mType == DT_ANON)
|
||||||
{
|
{
|
||||||
tdec->mBase = tdec->mBase->mBase;
|
tdec->mBase = tdec->mBase->mBase;
|
||||||
|
@ -7533,6 +7596,8 @@ void Parser::ParseTemplateDeclaration(void)
|
||||||
// Function template
|
// Function template
|
||||||
mTemplateScope = tdec->mScope;
|
mTemplateScope = tdec->mScope;
|
||||||
|
|
||||||
|
ConsumeTokenIf(TK_INLINE);
|
||||||
|
|
||||||
Declaration* bdec = ParseBaseTypeDeclaration(0, false);
|
Declaration* bdec = ParseBaseTypeDeclaration(0, false);
|
||||||
Declaration* adec = ParsePostfixDeclaration();
|
Declaration* adec = ParsePostfixDeclaration();
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ public:
|
||||||
DeclarationScope * mGlobals, * mScope, * mTemplateScope;
|
DeclarationScope * mGlobals, * mScope, * mTemplateScope;
|
||||||
int mLocalIndex;
|
int mLocalIndex;
|
||||||
CompilationUnits * mCompilationUnits;
|
CompilationUnits * mCompilationUnits;
|
||||||
Declaration * mThisPointer, * mReturnType;
|
Declaration * mThisPointer, * mReturnType, * mFunction;
|
||||||
|
|
||||||
LinkerSection * mCodeSection, * mDataSection, * mBSSection;
|
LinkerSection * mCodeSection, * mDataSection, * mBSSection;
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ protected:
|
||||||
Expression* CleanupExpression(Expression* exp);
|
Expression* CleanupExpression(Expression* exp);
|
||||||
|
|
||||||
Declaration* ParseBaseTypeDeclaration(uint64 flags, bool qualified);
|
Declaration* ParseBaseTypeDeclaration(uint64 flags, bool qualified);
|
||||||
Declaration* ParseDeclaration(Declaration* pdec, bool variable, bool expression, Declaration * pthis = nullptr);
|
Declaration* ParseDeclaration(Declaration* pdec, bool variable, bool expression, Declaration * pthis = nullptr, Declaration * ptempl = nullptr);
|
||||||
Declaration* ParseStructDeclaration(uint64 flags, DecType dt);
|
Declaration* ParseStructDeclaration(uint64 flags, DecType dt);
|
||||||
|
|
||||||
Declaration* CopyConstantInitializer(int offset, Declaration* dtype, Expression* exp);
|
Declaration* CopyConstantInitializer(int offset, Declaration* dtype, Expression* exp);
|
||||||
|
|
|
@ -163,6 +163,7 @@ const char* TokenNames[] =
|
||||||
"'virtual'",
|
"'virtual'",
|
||||||
"'operator'",
|
"'operator'",
|
||||||
"'template'",
|
"'template'",
|
||||||
|
"'friend'",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1511,6 +1512,8 @@ void Scanner::NextRawToken(void)
|
||||||
mToken = TK_VIRTUAL;
|
mToken = TK_VIRTUAL;
|
||||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "template"))
|
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "template"))
|
||||||
mToken = TK_TEMPLATE;
|
mToken = TK_TEMPLATE;
|
||||||
|
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "friend"))
|
||||||
|
mToken = TK_FRIEND;
|
||||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "operator"))
|
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "operator"))
|
||||||
{
|
{
|
||||||
NextRawToken();
|
NextRawToken();
|
||||||
|
|
|
@ -162,6 +162,7 @@ enum Token
|
||||||
TK_VIRTUAL,
|
TK_VIRTUAL,
|
||||||
TK_OPERATOR,
|
TK_OPERATOR,
|
||||||
TK_TEMPLATE,
|
TK_TEMPLATE,
|
||||||
|
TK_FRIEND,
|
||||||
|
|
||||||
NUM_TOKENS
|
NUM_TOKENS
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue