Add opp::function
This commit is contained in:
parent
a22dfa6ba7
commit
af38f64a99
|
@ -27,6 +27,9 @@ rem @echo off
|
|||
@call :testh opp_list.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh opp_functional.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :testh operatoroverload.cpp
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
#include <opp/functional.h>
|
||||
|
||||
class Node
|
||||
{
|
||||
public:
|
||||
virtual int eval(void) const = 0;
|
||||
};
|
||||
|
||||
class ConstNode : public Node
|
||||
{
|
||||
private:
|
||||
int v;
|
||||
public:
|
||||
ConstNode(int v_) : v(v_) {}
|
||||
virtual int eval(void) const
|
||||
{
|
||||
return v;
|
||||
}
|
||||
};
|
||||
|
||||
class BinaryNode : public Node
|
||||
{
|
||||
private:
|
||||
opp::function<int(int, int)> op;
|
||||
Node * left, * right;
|
||||
public:
|
||||
BinaryNode(opp::function<int(int, int)> op_, Node * left_, Node * right_);
|
||||
|
||||
virtual int eval(void) const
|
||||
{
|
||||
return op(left->eval(), right->eval());
|
||||
}
|
||||
};
|
||||
|
||||
inline BinaryNode::BinaryNode(opp::function<int(int, int)> op_, Node * left_, Node * right_)
|
||||
: op(op_), left(left_), right(right_) {}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
Node * s1 =
|
||||
new BinaryNode([=](int a, int b){return a + b;},
|
||||
new ConstNode(7), new ConstNode(11)
|
||||
);
|
||||
|
||||
return s1->eval() - 18;
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
#ifndef OPP_FUNCTIONAL_H
|
||||
#define OPP_FUNCTIONAL_H
|
||||
|
||||
namespace opp
|
||||
{
|
||||
template <class F>
|
||||
class function;
|
||||
|
||||
template <class R, class ... P>
|
||||
class function<R(P...)>
|
||||
{
|
||||
private:
|
||||
struct callif
|
||||
{
|
||||
virtual R call(P...) = 0;
|
||||
virtual ~callif() {}
|
||||
virtual callif * clone(void) const = 0;
|
||||
};
|
||||
|
||||
template<class CA>
|
||||
struct callable : callif
|
||||
{
|
||||
CA ca;
|
||||
|
||||
callable(CA ca_) : ca(ca_) {}
|
||||
|
||||
R call(P... p) {return ca(p...);}
|
||||
|
||||
callif * clone(void) const
|
||||
{
|
||||
return new callable(ca);
|
||||
}
|
||||
};
|
||||
|
||||
callif * c;
|
||||
public:
|
||||
template <class F>
|
||||
function(F f)
|
||||
{
|
||||
c = new callable<F>(f);
|
||||
}
|
||||
|
||||
function(const function & f)
|
||||
{
|
||||
c = f.c->clone();
|
||||
}
|
||||
#if 0
|
||||
function(function && f)
|
||||
{
|
||||
c = f.c;
|
||||
f.c = nullptr;
|
||||
}
|
||||
|
||||
function & operator=(const function & f)
|
||||
{
|
||||
if (c != f.c)
|
||||
{
|
||||
delete c;
|
||||
c = f.c;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
function & operator=(function && f)
|
||||
{
|
||||
if (c != f.c)
|
||||
{
|
||||
c = f.c;
|
||||
f.c = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
~function(void)
|
||||
{
|
||||
delete c;
|
||||
}
|
||||
|
||||
R operator()(P ... p) const
|
||||
{
|
||||
return c->call(p...);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -206,7 +206,10 @@ void Expression::Dump(int ident) const
|
|||
printf("INDEX");
|
||||
break;
|
||||
case EX_QUALIFY:
|
||||
printf("QUALIFY<%s>", mDecValue->mIdent->mString);
|
||||
if (mDecValue->mIdent)
|
||||
printf("QUALIFY<%s>", mDecValue->mIdent->mString);
|
||||
else
|
||||
printf("QUALIFY<%d>", mDecValue->mOffset);
|
||||
break;
|
||||
case EX_CALL:
|
||||
printf("CALL");
|
||||
|
@ -1463,22 +1466,27 @@ const Ident* Declaration::MangleIdent(void)
|
|||
else if (mType == DT_PACK_TYPE)
|
||||
{
|
||||
Declaration* dec = mParams;
|
||||
while (dec)
|
||||
if (dec)
|
||||
{
|
||||
const Ident* id = dec->MangleIdent();
|
||||
|
||||
if (id)
|
||||
while (dec)
|
||||
{
|
||||
if (mMangleIdent)
|
||||
mMangleIdent = mMangleIdent->Mangle(id->mString);
|
||||
else
|
||||
mMangleIdent = id;
|
||||
}
|
||||
const Ident* id = dec->MangleIdent();
|
||||
|
||||
dec = dec->mNext;
|
||||
if (dec)
|
||||
mMangleIdent = mMangleIdent->Mangle(",");
|
||||
if (id)
|
||||
{
|
||||
if (mMangleIdent)
|
||||
mMangleIdent = mMangleIdent->Mangle(id->mString);
|
||||
else
|
||||
mMangleIdent = id;
|
||||
}
|
||||
|
||||
dec = dec->mNext;
|
||||
if (dec)
|
||||
mMangleIdent = mMangleIdent->Mangle(",");
|
||||
}
|
||||
}
|
||||
else
|
||||
mMangleIdent = Ident::Unique("void");
|
||||
}
|
||||
else
|
||||
mMangleIdent = mQualIdent;
|
||||
|
@ -1618,6 +1626,7 @@ bool Declaration::ResolveTemplate(Expression* pexp, Declaration* tdec)
|
|||
else
|
||||
tpdec->mIdent = pdec->mBase->mIdent;
|
||||
tpdec->mParams = phead;
|
||||
tpdec->mFlags |= DTF_DEFINED;
|
||||
mScope->Insert(tpdec->mIdent, tpdec);
|
||||
}
|
||||
else
|
||||
|
@ -1702,14 +1711,44 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
|
|||
|
||||
Declaration* fpdec = fdec->mParams;
|
||||
Declaration* tpdec = tdec->mParams;
|
||||
while (fpdec && tpdec)
|
||||
while (tpdec)
|
||||
{
|
||||
if (tpdec->mBase->mType == DT_PACK_TEMPLATE)
|
||||
{
|
||||
if (fpdec->mBase->mType == DT_PACK_TEMPLATE)
|
||||
mScope->Insert(tdec->mIdent, fpdec);
|
||||
else
|
||||
{
|
||||
Declaration* ptdec = new Declaration(fdec->mLocation, DT_PACK_TYPE);
|
||||
Declaration* ppdec = nullptr;
|
||||
while (fpdec)
|
||||
{
|
||||
Declaration* pdec = fpdec->mBase->Clone();
|
||||
if (ppdec)
|
||||
ppdec->mNext = pdec;
|
||||
else
|
||||
ptdec->mParams = pdec;
|
||||
ppdec = pdec;
|
||||
fpdec = fpdec->mNext;
|
||||
}
|
||||
|
||||
ptdec->mFlags |= DTF_DEFINED;
|
||||
mScope->Insert(tpdec->mBase->mIdent, ptdec);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!fpdec)
|
||||
return false;
|
||||
|
||||
if (!ResolveTemplate(fpdec->mBase, tpdec->mBase))
|
||||
return false;
|
||||
|
||||
fpdec = fpdec->mNext;
|
||||
tpdec = tpdec->mNext;
|
||||
}
|
||||
if (fpdec || tpdec)
|
||||
if (fpdec)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
@ -1758,6 +1797,39 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
|
|||
}
|
||||
else if (tdec->mType == DT_PACK_TEMPLATE)
|
||||
{
|
||||
Declaration* pdec;
|
||||
if (tdec->mBase)
|
||||
{
|
||||
pdec = mScope->Lookup(tdec->mBase->mIdent);
|
||||
if (!pdec)
|
||||
return false;
|
||||
}
|
||||
else if (fdec->mType == DT_PACK_TYPE)
|
||||
{
|
||||
mScope->Insert(tdec->mIdent, fdec);
|
||||
}
|
||||
else
|
||||
{
|
||||
pdec = mScope->Lookup(tdec->mIdent);
|
||||
if (!pdec)
|
||||
{
|
||||
pdec = new Declaration(fdec->mLocation, DT_PACK_TYPE);
|
||||
mScope->Insert(tdec->mIdent, pdec);
|
||||
}
|
||||
|
||||
if (!pdec->mParams)
|
||||
{
|
||||
pdec->mParams = fdec->Clone();
|
||||
}
|
||||
else
|
||||
{
|
||||
Declaration* ppdec = pdec->mParams;
|
||||
while (ppdec->mNext)
|
||||
ppdec = ppdec->mNext;
|
||||
ppdec->mNext = fdec->Clone();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (tdec->mType == DT_TYPE_STRUCT && fdec->mType == DT_TYPE_STRUCT && tdec->mTemplate)
|
||||
|
@ -1832,7 +1904,7 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
|
|||
return false;
|
||||
}
|
||||
else
|
||||
return tdec->CanAssign(fdec);
|
||||
return tdec->IsSame(fdec);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ enum DecType
|
|||
DT_PACK_VARIABLE,
|
||||
DT_PACK_ARGUMENT,
|
||||
DT_PACK_TYPE,
|
||||
DT_PACK_ANON,
|
||||
|
||||
DT_VARIABLE,
|
||||
DT_ARGUMENT,
|
||||
|
|
|
@ -305,7 +305,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* p
|
|||
|
||||
return v;
|
||||
}
|
||||
else if (type->mType == DT_TYPE_STRUCT && type->mBase->IsSubType(v.mType))
|
||||
else if (type->mType == DT_TYPE_STRUCT && type->mBase && type->mBase->IsSubType(v.mType))
|
||||
{
|
||||
v.mType = type;
|
||||
return v;
|
||||
|
|
|
@ -49030,7 +49030,7 @@ void NativeCodeProcedure::Optimize(void)
|
|||
}
|
||||
}
|
||||
|
||||
if (step > 4)
|
||||
if (step > 4 && step != 6)
|
||||
{
|
||||
ResetVisited();
|
||||
if (mEntryBlock->ShortcutBlockExit())
|
||||
|
|
|
@ -187,8 +187,22 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio
|
|||
}
|
||||
|
||||
if (ptempl)
|
||||
{
|
||||
ptempl->mBase = dec;
|
||||
|
||||
if (mScanner->mToken == TK_LESS_THAN)
|
||||
{
|
||||
int level = 0;
|
||||
do {
|
||||
if (mScanner->mToken == TK_LESS_THAN)
|
||||
level++;
|
||||
else if (mScanner->mToken == TK_GREATER_THAN)
|
||||
level--;
|
||||
mScanner->NextToken();
|
||||
} while (level > 0);
|
||||
}
|
||||
}
|
||||
|
||||
if ((mCompilerOptions & COPT_CPLUSPLUS) && mScanner->mToken == TK_COLON)
|
||||
{
|
||||
mScanner->NextToken();
|
||||
|
@ -286,7 +300,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio
|
|||
}
|
||||
else if (ConsumeTokenIf(TK_TEMPLATE))
|
||||
{
|
||||
ParseTemplateDeclaration(pthis);
|
||||
Declaration * tdec = ParseTemplateDeclaration(pthis);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -810,6 +824,20 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified, Decl
|
|||
dec = nullptr;
|
||||
}
|
||||
|
||||
if (!dec && mThisPointer && !mScope->Lookup(pident, SLEVEL_FUNCTION))
|
||||
{
|
||||
int offset;
|
||||
uint64 flags;
|
||||
|
||||
if (mThisPointer->mType == DT_ARGUMENT)
|
||||
dec = MemberLookup(mThisPointer->mBase->mBase, mScanner->mTokenIdent, offset, flags);
|
||||
else if (mThisPointer->mType == DT_TYPE_POINTER)
|
||||
dec = MemberLookup(mThisPointer->mBase, mScanner->mTokenIdent, offset, flags);
|
||||
|
||||
if (dec && dec->mTemplate)
|
||||
dec = ParseTemplateExpansion(dec->mTemplate, nullptr);
|
||||
}
|
||||
|
||||
if (!dec)
|
||||
{
|
||||
dec = mScope->Lookup(pident);
|
||||
|
@ -1138,8 +1166,8 @@ Declaration* Parser::ParsePostfixDeclaration(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Identifier expected");
|
||||
dec = new Declaration(mScanner->mLocation, DT_ANON);
|
||||
dec = new Declaration(mScanner->mLocation, DT_PACK_ANON);
|
||||
dec->mIdent = mScanner->mTokenIdent;
|
||||
dec->mBase = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -1254,8 +1282,10 @@ Declaration * Parser::ParseFunctionDeclaration(Declaration* bdec)
|
|||
}
|
||||
|
||||
Declaration* bdec = ParseBaseTypeDeclaration(0, true);
|
||||
Declaration* adec = ParsePostfixDeclaration();
|
||||
// if (bdec->mType == DT_PACK_TEMPLATE)
|
||||
// ConsumeToken(TK_ELLIPSIS);
|
||||
|
||||
Declaration* adec = ParsePostfixDeclaration();
|
||||
adec = ReverseDeclaration(adec, bdec);
|
||||
|
||||
if (adec->mBase->mType == DT_TYPE_VOID)
|
||||
|
@ -1269,7 +1299,7 @@ Declaration * Parser::ParseFunctionDeclaration(Declaration* bdec)
|
|||
if (!(adec->mBase->mFlags & DTF_DEFINED) && adec->mBase->mType != DT_TYPE_ARRAY && !adec->mBase->mTemplate)
|
||||
mErrors->Error(adec->mLocation, EERR_UNDEFINED_OBJECT, "Type of argument not defined");
|
||||
|
||||
if (adec->mType == DT_PACK_VARIABLE)
|
||||
if (adec->mType == DT_PACK_VARIABLE || adec->mType == DT_PACK_ANON)
|
||||
{
|
||||
adec->mType = DT_PACK_ARGUMENT;
|
||||
if (adec->mBase)
|
||||
|
@ -3631,6 +3661,10 @@ Expression* Parser::AddFunctionCallRefReturned(Expression* exp)
|
|||
pex->mDecValue = nullptr;
|
||||
pex->mDecType = vdec->mBase;
|
||||
}
|
||||
else if (pex->mType == EX_CONSTRUCT && !pdec->IsReference())
|
||||
{
|
||||
pex->mLeft->mRight = nullptr;
|
||||
}
|
||||
|
||||
pdec = pdec->mNext;
|
||||
}
|
||||
|
@ -5284,7 +5318,20 @@ Expression* Parser::ParseLambdaExpression(void)
|
|||
return vexp;
|
||||
}
|
||||
|
||||
Expression* Parser::ParseSimpleExpression(bool lhs)
|
||||
Declaration* Parser::ParseTypeID(bool tid, Declaration* bdec)
|
||||
{
|
||||
Declaration * dec = bdec ? bdec : ParseBaseTypeDeclaration(0, true);
|
||||
|
||||
while (ConsumeTokenIf(TK_MUL))
|
||||
dec = dec->BuildPointer(mScanner->mLocation);
|
||||
while (ConsumeTokenIf(TK_BINARY_AND))
|
||||
dec = dec->BuildReference(mScanner->mLocation);
|
||||
if (tid && mScanner->mToken == TK_OPEN_PARENTHESIS)
|
||||
dec = ParseFunctionDeclaration(dec);
|
||||
return dec;
|
||||
}
|
||||
|
||||
Expression* Parser::ParseSimpleExpression(bool lhs, bool tid)
|
||||
{
|
||||
Declaration* dec = nullptr;
|
||||
Expression* exp = nullptr, * rexp = nullptr;
|
||||
|
@ -5302,32 +5349,14 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
|
|||
case TK_VOID:
|
||||
case TK_UNSIGNED:
|
||||
case TK_SIGNED:
|
||||
if (lhs)
|
||||
exp = ParseDeclarationExpression(nullptr);
|
||||
else
|
||||
{
|
||||
exp = new Expression(mScanner->mLocation, EX_TYPE);
|
||||
exp->mDecValue = nullptr;
|
||||
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;
|
||||
case TK_CONST:
|
||||
if (lhs)
|
||||
exp = ParseDeclarationExpression(nullptr);
|
||||
else
|
||||
{
|
||||
mScanner->NextToken();
|
||||
exp = new Expression(mScanner->mLocation, EX_TYPE);
|
||||
exp->mDecValue = nullptr;
|
||||
exp->mDecType = ParseBaseTypeDeclaration(DTF_CONST, true);
|
||||
while (ConsumeTokenIf(TK_MUL))
|
||||
exp->mDecType = exp->mDecType->BuildPointer(mScanner->mLocation);
|
||||
while (ConsumeTokenIf(TK_BINARY_AND))
|
||||
exp->mDecType = exp->mDecType->BuildReference(mScanner->mLocation);
|
||||
exp->mDecType = ParseTypeID(tid);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -5677,11 +5706,7 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
|
|||
{
|
||||
exp = new Expression(mScanner->mLocation, EX_TYPE);
|
||||
exp->mDecValue = nullptr;
|
||||
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);
|
||||
exp->mDecType = ParseTypeID(tid, dec);
|
||||
}
|
||||
}
|
||||
else if (dec->mType == DT_CONST_TEMPLATE)
|
||||
|
@ -6069,6 +6094,20 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
|
|||
{
|
||||
if (fdec->mTemplate)
|
||||
{
|
||||
// this is a constructor, so avoid instantiating a single parameter with the type itself
|
||||
// as this would only lead to misery and pain and a crashing recursion
|
||||
if (fdec->mIdent->mString[0] == '+')
|
||||
{
|
||||
if (fdec->mBase->mParams && fdec->mBase->mParams->mNext && !fdec->mBase->mParams->mNext->mNext &&
|
||||
fdec->mBase->mParams->mNext->mBase->mType == DT_TYPE_TEMPLATE &&
|
||||
fdec->mBase->mParams->mBase->mBase)
|
||||
{
|
||||
if (pexp->mRight && pexp->mRight->mDecType->IsConstSame(fdec->mBase->mParams->mBase->mBase))
|
||||
return NOOVERLOAD;
|
||||
printf("oopsie");
|
||||
}
|
||||
}
|
||||
|
||||
Declaration* tdec = new Declaration(mScanner->mLocation, DT_TEMPLATE);
|
||||
tdec->mScope = new DeclarationScope(nullptr, SLEVEL_TEMPLATE);
|
||||
if (!tdec->CanResolveTemplate(pexp, fdec))
|
||||
|
@ -6309,7 +6348,8 @@ bool Parser::CanCoerceExpression(Expression* exp, Declaration* type)
|
|||
Declaration* fcons = type->mScope ? type->mScope->Lookup(type->mIdent->PreMangle("+")) : nullptr;
|
||||
if (fcons)
|
||||
{
|
||||
while (fcons && !(fcons->mBase->mParams && fcons->mBase->mParams->mNext && !fcons->mBase->mParams->mNext->mNext && fcons->mBase->mParams->mNext->mBase->CanAssign(tdec)))
|
||||
while (fcons && !(fcons->mBase->mParams && fcons->mBase->mParams->mNext && !fcons->mBase->mParams->mNext->mNext &&
|
||||
(fcons->mBase->mParams->mNext->mBase->mType == DT_TYPE_TEMPLATE || fcons->mBase->mParams->mNext->mBase->CanAssign(tdec))))
|
||||
fcons = fcons->mNext;
|
||||
|
||||
if (fcons)
|
||||
|
@ -6374,10 +6414,12 @@ Expression* Parser::CoerceExpression(Expression* exp, Declaration* type)
|
|||
Declaration* fcons = type->mScope ? type->mScope->Lookup(type->mIdent->PreMangle("+")) : nullptr;
|
||||
if (fcons)
|
||||
{
|
||||
#if 0
|
||||
while (fcons && !(fcons->mBase->mParams && fcons->mBase->mParams->mNext && !fcons->mBase->mParams->mNext->mNext && fcons->mBase->mParams->mNext->mBase->CanAssign(tdec)))
|
||||
fcons = fcons->mNext;
|
||||
|
||||
if (fcons)
|
||||
#endif
|
||||
{
|
||||
Declaration* vdec = AllocTempVar(type->ToMutableType());
|
||||
#if 0
|
||||
|
@ -6399,7 +6441,6 @@ Expression* Parser::CoerceExpression(Expression* exp, Declaration* type)
|
|||
|
||||
Expression* fexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||
fexp->mLeft = cexp;
|
||||
|
||||
fexp->mRight = exp;
|
||||
|
||||
Expression* texp = new Expression(mScanner->mLocation, EX_PREFIX);
|
||||
|
@ -6415,6 +6456,8 @@ Expression* Parser::CoerceExpression(Expression* exp, Declaration* type)
|
|||
lexp->mRight = fexp->mRight;
|
||||
fexp->mRight = lexp;
|
||||
|
||||
fexp = ResolveOverloadCall(fexp);
|
||||
|
||||
Expression* dexp = nullptr;
|
||||
if (type->mDestructor)
|
||||
{
|
||||
|
@ -6558,7 +6601,7 @@ Expression * Parser::ResolveOverloadCall(Expression* exp, Expression* exp2)
|
|||
fdec = exp->mLeft->mDecValue;
|
||||
while (fdec)
|
||||
{
|
||||
int d = OverloadDistance(exp->mLeft->mDecValue, exp->mRight);
|
||||
int d = OverloadDistance(fdec, exp->mRight);
|
||||
fdec = fdec->mNext;
|
||||
}
|
||||
#endif
|
||||
|
@ -6568,6 +6611,8 @@ Expression * Parser::ResolveOverloadCall(Expression* exp, Expression* exp2)
|
|||
mErrors->Error(exp->mLocation, ERRO_AMBIGUOUS_FUNCTION_CALL, "Ambiguous function call", exp->mLeft->mDecValue->mQualIdent);
|
||||
else
|
||||
{
|
||||
assert(dbest);
|
||||
|
||||
exp->mLeft->mDecValue = dbest;
|
||||
exp->mLeft->mDecType = dbest->mBase;
|
||||
exp->mDecType = dbest->mBase->mBase;
|
||||
|
@ -6838,9 +6883,13 @@ Expression* Parser::ParsePostfixExpression(bool lhs)
|
|||
}
|
||||
|
||||
nexp = ResolveOverloadCall(nexp);
|
||||
nexp->mDecType = exp->mDecType->mBase;
|
||||
Declaration* fdec = nexp->mLeft->mDecType;
|
||||
if (fdec->mType == DT_TYPE_POINTER)
|
||||
fdec = fdec->mBase;
|
||||
|
||||
if (nexp->mLeft->mDecType->mFlags & DTF_VIRTUAL)
|
||||
nexp->mDecType = fdec->mBase;
|
||||
|
||||
if (fdec->mFlags & DTF_VIRTUAL)
|
||||
{
|
||||
if (parentCall)
|
||||
exp->mDecType->mFlags |= DTF_STACKCALL;
|
||||
|
@ -9372,7 +9421,7 @@ Expression* Parser::ParseSwitchStatement(void)
|
|||
return sexp;
|
||||
}
|
||||
|
||||
int Parser::ExpansionDistance(Declaration* tdec, Declaration* spec)
|
||||
int Parser::ExpansionDistance(Declaration* tdec, Declaration* spec, Declaration* xtdec)
|
||||
{
|
||||
Declaration* ptdec = tdec->mParams;
|
||||
Declaration* psdec = spec->mParams;
|
||||
|
@ -9387,19 +9436,32 @@ int Parser::ExpansionDistance(Declaration* tdec, Declaration* spec)
|
|||
{
|
||||
if (ptdec->mBase)
|
||||
{
|
||||
if (ptdec->mBase->mInteger != psdec->mBase->mInteger)
|
||||
return NOOVERLOAD;
|
||||
if (ptdec->mBase->mType == DT_CONST_INTEGER)
|
||||
{
|
||||
if (ptdec->mBase->mInteger != psdec->mBase->mInteger)
|
||||
return NOOVERLOAD;
|
||||
}
|
||||
else if (ptdec->mBase->mType == DT_CONST_TEMPLATE)
|
||||
{
|
||||
Declaration* pdec = xtdec->mScope->Insert(ptdec->mBase->mIdent, psdec->mBase);
|
||||
cost += 100;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Declaration* pdec = xtdec->mScope->Insert(ptdec->mIdent, psdec->mBase);
|
||||
cost += 100;
|
||||
}
|
||||
}
|
||||
else if (ptdec->mType == DT_TYPE_TEMPLATE && psdec->mType == DT_TYPE_TEMPLATE)
|
||||
{
|
||||
if (ptdec->mBase)
|
||||
{
|
||||
if (!ptdec->mBase->IsSame(psdec->mBase))
|
||||
if (!xtdec->ResolveTemplate(psdec->mBase, ptdec->mBase))
|
||||
return NOOVERLOAD;
|
||||
}
|
||||
else if (!xtdec->ResolveTemplate(psdec->mBase, ptdec))
|
||||
return NOOVERLOAD;
|
||||
else
|
||||
cost += 100;
|
||||
}
|
||||
|
@ -9422,6 +9484,9 @@ int Parser::ExpansionDistance(Declaration* tdec, Declaration* spec)
|
|||
}
|
||||
else if (psdec->mBase)
|
||||
{
|
||||
if (!xtdec->ResolveTemplate(psdec->mBase, ptdec))
|
||||
return NOOVERLOAD;
|
||||
|
||||
Declaration* dec = psdec->mBase->mParams;
|
||||
while (dec)
|
||||
{
|
||||
|
@ -9437,6 +9502,14 @@ int Parser::ExpansionDistance(Declaration* tdec, Declaration* spec)
|
|||
ptdec = ptdec->mBase->mParams;
|
||||
continue;
|
||||
}
|
||||
else if (psdec->mBase)
|
||||
{
|
||||
if (!xtdec->ResolveTemplate(psdec->mBase, ptdec))
|
||||
return NOOVERLOAD;
|
||||
psdec = psdec->mNext;
|
||||
cost += 200;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (psdec)
|
||||
|
@ -9471,6 +9544,93 @@ int Parser::ExpansionDistance(Declaration* tdec, Declaration* spec)
|
|||
return cost;
|
||||
}
|
||||
|
||||
void Parser::ParseTemplateArguments(Declaration* tmpld, Declaration* tdec)
|
||||
{
|
||||
ConsumeToken(TK_LESS_THAN);
|
||||
|
||||
Declaration* tparm = tmpld->mParams;
|
||||
Declaration* ppdec = nullptr;
|
||||
|
||||
if (!ConsumeTokenIf(TK_GREATER_THAN))
|
||||
{
|
||||
do
|
||||
{
|
||||
Expression* exp;
|
||||
|
||||
if (tparm && tparm->mType == DT_TYPE_TEMPLATE)
|
||||
exp = ParseSimpleExpression(false, true);
|
||||
else
|
||||
exp = ParseShiftExpression(false);
|
||||
|
||||
Declaration* pdec = nullptr;
|
||||
|
||||
if (exp->mType == EX_TYPE)
|
||||
{
|
||||
pdec = new Declaration(exp->mLocation, DT_TYPE_TEMPLATE);
|
||||
pdec->mBase = exp->mDecType;
|
||||
}
|
||||
else if (exp->mType == EX_PACK_TYPE)
|
||||
{
|
||||
ConsumeToken(TK_ELLIPSIS);
|
||||
|
||||
if (exp->mDecType->mType == DT_PACK_TYPE)
|
||||
{
|
||||
Declaration* ptdec = exp->mDecType->mParams;
|
||||
while (ptdec)
|
||||
{
|
||||
pdec = new Declaration(exp->mLocation, DT_TYPE_TEMPLATE);
|
||||
pdec->mBase = ptdec;
|
||||
|
||||
if (pdec)
|
||||
{
|
||||
if (ppdec)
|
||||
ppdec->mNext = pdec;
|
||||
else
|
||||
tdec->mParams = pdec;
|
||||
ppdec = pdec;
|
||||
}
|
||||
|
||||
ptdec = ptdec->mNext;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
pdec = new Declaration(exp->mLocation, DT_PACK_TEMPLATE);
|
||||
pdec->mBase = exp->mDecType;
|
||||
}
|
||||
}
|
||||
else if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_FUNCTION)
|
||||
{
|
||||
pdec = new Declaration(exp->mLocation, DT_TYPE_TEMPLATE);
|
||||
pdec->mBase = exp->mDecValue;
|
||||
}
|
||||
else if (exp->mType == EX_CONSTANT && (exp->mDecValue->mType == DT_CONST_INTEGER || exp->mDecValue->mType == DT_CONST_TEMPLATE))
|
||||
{
|
||||
pdec = new Declaration(exp->mLocation, DT_CONST_TEMPLATE);
|
||||
pdec->mBase = exp->mDecValue;
|
||||
}
|
||||
else
|
||||
mErrors->Error(exp->mLocation, EERR_TEMPLATE_PARAMS, "Template specification expected");
|
||||
|
||||
if (pdec)
|
||||
{
|
||||
if (ppdec)
|
||||
ppdec->mNext = pdec;
|
||||
else
|
||||
tdec->mParams = pdec;
|
||||
ppdec = pdec;
|
||||
}
|
||||
|
||||
if (tparm)
|
||||
tparm = tparm->mNext;
|
||||
|
||||
} while (ConsumeTokenIf(TK_COMMA));
|
||||
|
||||
ConsumeToken(TK_GREATER_THAN);
|
||||
}
|
||||
}
|
||||
|
||||
Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* expd)
|
||||
{
|
||||
Declaration * tdec = new Declaration(mScanner->mLocation, DT_TEMPLATE);
|
||||
|
@ -9512,79 +9672,7 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
|||
}
|
||||
else
|
||||
{
|
||||
ConsumeToken(TK_LESS_THAN);
|
||||
|
||||
Declaration* ppdec = nullptr;
|
||||
|
||||
if (!ConsumeTokenIf(TK_GREATER_THAN))
|
||||
{
|
||||
do
|
||||
{
|
||||
Expression* exp = ParseShiftExpression(false);
|
||||
Declaration* pdec = nullptr;
|
||||
|
||||
if (exp->mType == EX_TYPE)
|
||||
{
|
||||
pdec = new Declaration(exp->mLocation, DT_TYPE_TEMPLATE);
|
||||
pdec->mBase = exp->mDecType;
|
||||
}
|
||||
else if (exp->mType == EX_PACK_TYPE)
|
||||
{
|
||||
ConsumeToken(TK_ELLIPSIS);
|
||||
|
||||
if (exp->mDecType->mType == DT_PACK_TYPE)
|
||||
{
|
||||
Declaration* ptdec = exp->mDecType->mParams;
|
||||
while (ptdec)
|
||||
{
|
||||
pdec = new Declaration(exp->mLocation, DT_TYPE_TEMPLATE);
|
||||
pdec->mBase = ptdec;
|
||||
|
||||
if (pdec)
|
||||
{
|
||||
if (ppdec)
|
||||
ppdec->mNext = pdec;
|
||||
else
|
||||
tdec->mParams = pdec;
|
||||
ppdec = pdec;
|
||||
}
|
||||
|
||||
ptdec = ptdec->mNext;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
pdec = new Declaration(exp->mLocation, DT_PACK_TEMPLATE);
|
||||
pdec->mBase = exp->mDecType;
|
||||
}
|
||||
}
|
||||
else if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_FUNCTION)
|
||||
{
|
||||
pdec = new Declaration(exp->mLocation, DT_TYPE_TEMPLATE);
|
||||
pdec->mBase = exp->mDecValue;
|
||||
}
|
||||
else if (exp->mType == EX_CONSTANT && (exp->mDecValue->mType == DT_CONST_INTEGER || exp->mDecValue->mType == DT_CONST_TEMPLATE))
|
||||
{
|
||||
pdec = new Declaration(exp->mLocation, DT_CONST_TEMPLATE);
|
||||
pdec->mBase = exp->mDecValue;
|
||||
}
|
||||
else
|
||||
mErrors->Error(exp->mLocation, EERR_TEMPLATE_PARAMS, "Template specification expected");
|
||||
|
||||
if (pdec)
|
||||
{
|
||||
if (ppdec)
|
||||
ppdec->mNext = pdec;
|
||||
else
|
||||
tdec->mParams = pdec;
|
||||
ppdec = pdec;
|
||||
}
|
||||
|
||||
} while (ConsumeTokenIf(TK_COMMA));
|
||||
|
||||
ConsumeToken(TK_GREATER_THAN);
|
||||
}
|
||||
ParseTemplateArguments(tmpld, tdec);
|
||||
}
|
||||
|
||||
while (!tmpld->mTokens)
|
||||
|
@ -9616,11 +9704,16 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
|||
Declaration* etdec = nullptr;
|
||||
|
||||
Declaration* dec = tmpld;
|
||||
Declaration* mxtdec = nullptr;
|
||||
while (dec)
|
||||
{
|
||||
int dist = ExpansionDistance(dec, tdec);
|
||||
Declaration* xtdec = new Declaration(mScanner->mLocation, DT_TEMPLATE);
|
||||
xtdec->mScope = new DeclarationScope(nullptr, SLEVEL_TEMPLATE);
|
||||
|
||||
int dist = ExpansionDistance(dec, tdec, xtdec);
|
||||
if (dist < mindist)
|
||||
{
|
||||
mxtdec = xtdec;
|
||||
mindist = dist;
|
||||
etdec = dec;
|
||||
}
|
||||
|
@ -9635,22 +9728,17 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
|||
tmpld = etdec;
|
||||
|
||||
dec = tdec->mParams;
|
||||
Declaration * pdec = tmpld->mParams;
|
||||
Declaration * pdec = tmpld->mBase->mTemplate->mParams;
|
||||
|
||||
Declaration * ppdec = nullptr;
|
||||
while (pdec)
|
||||
{
|
||||
Declaration* rdec = mxtdec->mScope->Lookup(pdec->mIdent);
|
||||
if (pdec->mType == DT_PACK_TEMPLATE)
|
||||
{
|
||||
if (!dec)
|
||||
if (!rdec)
|
||||
{
|
||||
Declaration* packd = new Declaration(tdec->mLocation, DT_PACK_TEMPLATE);
|
||||
packd->mBase = new Declaration(tdec->mLocation, DT_PACK_TYPE);
|
||||
if (ppdec)
|
||||
ppdec->mNext = packd;
|
||||
else
|
||||
tdec->mParams = packd;
|
||||
dec = packd;
|
||||
rdec = new Declaration(tdec->mLocation, DT_PACK_TYPE);
|
||||
}
|
||||
else if (dec->mType != DT_PACK_TEMPLATE)
|
||||
{
|
||||
|
@ -9678,13 +9766,10 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
|||
}
|
||||
}
|
||||
|
||||
if (dec)
|
||||
if (rdec)
|
||||
{
|
||||
dec->mIdent = pdec->mIdent;
|
||||
tdec->mScope->Insert(dec->mIdent, dec->mBase);
|
||||
|
||||
ppdec = dec;
|
||||
dec = dec->mNext;
|
||||
// rdec->mIdent = pdec->mIdent;
|
||||
tdec->mScope->Insert(pdec->mIdent, rdec);
|
||||
}
|
||||
|
||||
pdec = pdec->mNext;
|
||||
|
@ -9871,7 +9956,19 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
|||
tpthis = tmpld->mClass;
|
||||
else if (expd && expd->mBase)
|
||||
tpthis = expd->mBase->BuildConstPointer(tdec->mLocation);
|
||||
#if 0
|
||||
if (tpthis)
|
||||
{
|
||||
DeclarationScope* oscope = p->mScope;
|
||||
tpthis->mBase->mScope->mParent = p->mScope;
|
||||
p->mScope = tpthis->mBase->mScope;
|
||||
|
||||
tdec->mBase = p->ParseDeclaration(nullptr, true, false, tpthis, tdec);
|
||||
|
||||
p->mScope = oscope;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
tdec->mBase = p->ParseDeclaration(nullptr, true, false, tpthis, tdec);
|
||||
}
|
||||
|
||||
|
@ -10153,6 +10250,20 @@ void Parser::ParseTemplateDeclarationBody(Declaration * tdec, Declaration * pthi
|
|||
bdec->mQualIdent = mScope->Mangle(mScanner->mTokenIdent);
|
||||
bdec->mScope = new DeclarationScope(nullptr, SLEVEL_CLASS, bdec->mQualIdent);
|
||||
|
||||
mScanner->NextToken();
|
||||
if (mScanner->mToken == TK_LESS_THAN)
|
||||
{
|
||||
Declaration* ptdec = new Declaration(mScanner->mLocation, DT_TEMPLATE);
|
||||
ptdec->mScope = new DeclarationScope(nullptr, SLEVEL_TEMPLATE);
|
||||
|
||||
mTemplateScope = tdec->mScope;
|
||||
ParseTemplateArguments(tdec, ptdec);
|
||||
|
||||
ptdec->mBase = bdec;
|
||||
ptdec->mParser = tdec->mParser;
|
||||
tdec = ptdec;
|
||||
}
|
||||
|
||||
while (mScanner->mToken != TK_SEMICOLON && mScanner->mToken != TK_OPEN_BRACE)
|
||||
mScanner->NextToken();
|
||||
|
||||
|
|
|
@ -111,7 +111,8 @@ protected:
|
|||
void ParseTemplateDeclarationBody(Declaration* tdec, Declaration* pthis);
|
||||
Declaration* FunctionAutoParamsToTemplate(Declaration* fdec);
|
||||
|
||||
int ExpansionDistance(Declaration* tdec, Declaration* spec);
|
||||
int ExpansionDistance(Declaration* tdec, Declaration* spec, Declaration* xtdec);
|
||||
void ParseTemplateArguments(Declaration* tmpld, Declaration* tdec);
|
||||
Declaration* ParseTemplateExpansion(Declaration* tmpld, Declaration* expd);
|
||||
void CompleteTemplateExpansion(Declaration* tmpld);
|
||||
|
||||
|
@ -124,7 +125,9 @@ protected:
|
|||
Expression* ExpandPackExpression(Expression* exp, Expression* pack, Expression* item);
|
||||
Expression* ParseBinaryFoldExpression(Expression * exp);
|
||||
|
||||
Expression* ParseSimpleExpression(bool lhs);
|
||||
Declaration* ParseTypeID(bool tid, Declaration * bdec = nullptr);
|
||||
|
||||
Expression* ParseSimpleExpression(bool lhs, bool tid = false);
|
||||
Expression* ParsePrefixExpression(bool lhs);
|
||||
Expression* ParsePostfixExpression(bool lhs);
|
||||
Expression* ParseMulExpression(bool lhs);
|
||||
|
|
|
@ -130,6 +130,12 @@
|
|||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_1328E18B9638422795616BABEAAFA600"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
}
|
||||
"Entry"
|
||||
{
|
||||
"MsmKey" = "8:_1393003825B9451084DB314DD4267AD5"
|
||||
"OwnerKey" = "8:_UNDEFINED"
|
||||
"MsmSig" = "8:_UNDEFINED"
|
||||
|
@ -1801,6 +1807,26 @@
|
|||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_1328E18B9638422795616BABEAAFA600"
|
||||
{
|
||||
"SourcePath" = "8:..\\include\\opp\\functional.h"
|
||||
"TargetName" = "8:functional.h"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_D76A1802AFD04C48A519C9F8700E53CC"
|
||||
"Condition" = "8:"
|
||||
"Transitive" = "11:FALSE"
|
||||
"Vital" = "11:TRUE"
|
||||
"ReadOnly" = "11:FALSE"
|
||||
"Hidden" = "11:FALSE"
|
||||
"System" = "11:FALSE"
|
||||
"Permanent" = "11:FALSE"
|
||||
"SharedLegacy" = "11:FALSE"
|
||||
"PackageAs" = "3:1"
|
||||
"Register" = "3:1"
|
||||
"Exclude" = "11:FALSE"
|
||||
"IsDependency" = "11:FALSE"
|
||||
"IsolateTo" = "8:"
|
||||
}
|
||||
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_1393003825B9451084DB314DD4267AD5"
|
||||
{
|
||||
"SourcePath" = "8:..\\samples\\memmap\\allmem.c"
|
||||
|
@ -6676,7 +6702,7 @@
|
|||
{
|
||||
"{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||
{
|
||||
"SourcePath" = "8:..\\Releasex64\\oscar64.exe"
|
||||
"SourcePath" = "8:..\\Debugx64\\oscar64.exe"
|
||||
"TargetName" = "8:"
|
||||
"Tag" = "8:"
|
||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||
|
|
Loading…
Reference in New Issue