Add opp::function
This commit is contained in:
parent
a22dfa6ba7
commit
af38f64a99
|
@ -27,6 +27,9 @@ rem @echo off
|
||||||
@call :testh opp_list.cpp
|
@call :testh opp_list.cpp
|
||||||
@if %errorlevel% neq 0 goto :error
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
@call :testh opp_functional.cpp
|
||||||
|
@if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
@call :testh operatoroverload.cpp
|
@call :testh operatoroverload.cpp
|
||||||
@if %errorlevel% neq 0 goto :error
|
@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");
|
printf("INDEX");
|
||||||
break;
|
break;
|
||||||
case EX_QUALIFY:
|
case EX_QUALIFY:
|
||||||
|
if (mDecValue->mIdent)
|
||||||
printf("QUALIFY<%s>", mDecValue->mIdent->mString);
|
printf("QUALIFY<%s>", mDecValue->mIdent->mString);
|
||||||
|
else
|
||||||
|
printf("QUALIFY<%d>", mDecValue->mOffset);
|
||||||
break;
|
break;
|
||||||
case EX_CALL:
|
case EX_CALL:
|
||||||
printf("CALL");
|
printf("CALL");
|
||||||
|
@ -1463,6 +1466,8 @@ const Ident* Declaration::MangleIdent(void)
|
||||||
else if (mType == DT_PACK_TYPE)
|
else if (mType == DT_PACK_TYPE)
|
||||||
{
|
{
|
||||||
Declaration* dec = mParams;
|
Declaration* dec = mParams;
|
||||||
|
if (dec)
|
||||||
|
{
|
||||||
while (dec)
|
while (dec)
|
||||||
{
|
{
|
||||||
const Ident* id = dec->MangleIdent();
|
const Ident* id = dec->MangleIdent();
|
||||||
|
@ -1480,6 +1485,9 @@ const Ident* Declaration::MangleIdent(void)
|
||||||
mMangleIdent = mMangleIdent->Mangle(",");
|
mMangleIdent = mMangleIdent->Mangle(",");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
mMangleIdent = Ident::Unique("void");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
mMangleIdent = mQualIdent;
|
mMangleIdent = mQualIdent;
|
||||||
|
|
||||||
|
@ -1618,6 +1626,7 @@ bool Declaration::ResolveTemplate(Expression* pexp, Declaration* tdec)
|
||||||
else
|
else
|
||||||
tpdec->mIdent = pdec->mBase->mIdent;
|
tpdec->mIdent = pdec->mBase->mIdent;
|
||||||
tpdec->mParams = phead;
|
tpdec->mParams = phead;
|
||||||
|
tpdec->mFlags |= DTF_DEFINED;
|
||||||
mScope->Insert(tpdec->mIdent, tpdec);
|
mScope->Insert(tpdec->mIdent, tpdec);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1702,14 +1711,44 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
|
||||||
|
|
||||||
Declaration* fpdec = fdec->mParams;
|
Declaration* fpdec = fdec->mParams;
|
||||||
Declaration* tpdec = tdec->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))
|
if (!ResolveTemplate(fpdec->mBase, tpdec->mBase))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fpdec = fpdec->mNext;
|
fpdec = fpdec->mNext;
|
||||||
tpdec = tpdec->mNext;
|
tpdec = tpdec->mNext;
|
||||||
}
|
}
|
||||||
if (fpdec || tpdec)
|
if (fpdec)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1758,6 +1797,39 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
|
||||||
}
|
}
|
||||||
else if (tdec->mType == DT_PACK_TEMPLATE)
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
else if (tdec->mType == DT_TYPE_STRUCT && fdec->mType == DT_TYPE_STRUCT && tdec->mTemplate)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return tdec->CanAssign(fdec);
|
return tdec->IsSame(fdec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ enum DecType
|
||||||
DT_PACK_VARIABLE,
|
DT_PACK_VARIABLE,
|
||||||
DT_PACK_ARGUMENT,
|
DT_PACK_ARGUMENT,
|
||||||
DT_PACK_TYPE,
|
DT_PACK_TYPE,
|
||||||
|
DT_PACK_ANON,
|
||||||
|
|
||||||
DT_VARIABLE,
|
DT_VARIABLE,
|
||||||
DT_ARGUMENT,
|
DT_ARGUMENT,
|
||||||
|
|
|
@ -305,7 +305,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* p
|
||||||
|
|
||||||
return v;
|
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;
|
v.mType = type;
|
||||||
return v;
|
return v;
|
||||||
|
|
|
@ -49030,7 +49030,7 @@ void NativeCodeProcedure::Optimize(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (step > 4)
|
if (step > 4 && step != 6)
|
||||||
{
|
{
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
if (mEntryBlock->ShortcutBlockExit())
|
if (mEntryBlock->ShortcutBlockExit())
|
||||||
|
|
|
@ -187,8 +187,22 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ptempl)
|
if (ptempl)
|
||||||
|
{
|
||||||
ptempl->mBase = dec;
|
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)
|
if ((mCompilerOptions & COPT_CPLUSPLUS) && mScanner->mToken == TK_COLON)
|
||||||
{
|
{
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
|
@ -286,7 +300,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio
|
||||||
}
|
}
|
||||||
else if (ConsumeTokenIf(TK_TEMPLATE))
|
else if (ConsumeTokenIf(TK_TEMPLATE))
|
||||||
{
|
{
|
||||||
ParseTemplateDeclaration(pthis);
|
Declaration * tdec = ParseTemplateDeclaration(pthis);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -810,6 +824,20 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified, Decl
|
||||||
dec = nullptr;
|
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)
|
if (!dec)
|
||||||
{
|
{
|
||||||
dec = mScope->Lookup(pident);
|
dec = mScope->Lookup(pident);
|
||||||
|
@ -1138,8 +1166,8 @@ Declaration* Parser::ParsePostfixDeclaration(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Identifier expected");
|
dec = new Declaration(mScanner->mLocation, DT_PACK_ANON);
|
||||||
dec = new Declaration(mScanner->mLocation, DT_ANON);
|
dec->mIdent = mScanner->mTokenIdent;
|
||||||
dec->mBase = nullptr;
|
dec->mBase = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1254,8 +1282,10 @@ Declaration * Parser::ParseFunctionDeclaration(Declaration* bdec)
|
||||||
}
|
}
|
||||||
|
|
||||||
Declaration* bdec = ParseBaseTypeDeclaration(0, true);
|
Declaration* bdec = ParseBaseTypeDeclaration(0, true);
|
||||||
Declaration* adec = ParsePostfixDeclaration();
|
// if (bdec->mType == DT_PACK_TEMPLATE)
|
||||||
|
// ConsumeToken(TK_ELLIPSIS);
|
||||||
|
|
||||||
|
Declaration* adec = ParsePostfixDeclaration();
|
||||||
adec = ReverseDeclaration(adec, bdec);
|
adec = ReverseDeclaration(adec, bdec);
|
||||||
|
|
||||||
if (adec->mBase->mType == DT_TYPE_VOID)
|
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)
|
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");
|
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;
|
adec->mType = DT_PACK_ARGUMENT;
|
||||||
if (adec->mBase)
|
if (adec->mBase)
|
||||||
|
@ -3631,6 +3661,10 @@ Expression* Parser::AddFunctionCallRefReturned(Expression* exp)
|
||||||
pex->mDecValue = nullptr;
|
pex->mDecValue = nullptr;
|
||||||
pex->mDecType = vdec->mBase;
|
pex->mDecType = vdec->mBase;
|
||||||
}
|
}
|
||||||
|
else if (pex->mType == EX_CONSTRUCT && !pdec->IsReference())
|
||||||
|
{
|
||||||
|
pex->mLeft->mRight = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
pdec = pdec->mNext;
|
pdec = pdec->mNext;
|
||||||
}
|
}
|
||||||
|
@ -5284,7 +5318,20 @@ Expression* Parser::ParseLambdaExpression(void)
|
||||||
return vexp;
|
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;
|
Declaration* dec = nullptr;
|
||||||
Expression* exp = nullptr, * rexp = nullptr;
|
Expression* exp = nullptr, * rexp = nullptr;
|
||||||
|
@ -5302,32 +5349,14 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
|
||||||
case TK_VOID:
|
case TK_VOID:
|
||||||
case TK_UNSIGNED:
|
case TK_UNSIGNED:
|
||||||
case TK_SIGNED:
|
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:
|
case TK_CONST:
|
||||||
if (lhs)
|
if (lhs)
|
||||||
exp = ParseDeclarationExpression(nullptr);
|
exp = ParseDeclarationExpression(nullptr);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mScanner->NextToken();
|
|
||||||
exp = new Expression(mScanner->mLocation, EX_TYPE);
|
exp = new Expression(mScanner->mLocation, EX_TYPE);
|
||||||
exp->mDecValue = nullptr;
|
exp->mDecValue = nullptr;
|
||||||
exp->mDecType = ParseBaseTypeDeclaration(DTF_CONST, true);
|
exp->mDecType = ParseTypeID(tid);
|
||||||
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;
|
||||||
|
|
||||||
|
@ -5677,11 +5706,7 @@ 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 = ParseTypeID(tid, 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_CONST_TEMPLATE)
|
else if (dec->mType == DT_CONST_TEMPLATE)
|
||||||
|
@ -6069,6 +6094,20 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
|
||||||
{
|
{
|
||||||
if (fdec->mTemplate)
|
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);
|
Declaration* tdec = new Declaration(mScanner->mLocation, DT_TEMPLATE);
|
||||||
tdec->mScope = new DeclarationScope(nullptr, SLEVEL_TEMPLATE);
|
tdec->mScope = new DeclarationScope(nullptr, SLEVEL_TEMPLATE);
|
||||||
if (!tdec->CanResolveTemplate(pexp, fdec))
|
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;
|
Declaration* fcons = type->mScope ? type->mScope->Lookup(type->mIdent->PreMangle("+")) : nullptr;
|
||||||
if (fcons)
|
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;
|
fcons = fcons->mNext;
|
||||||
|
|
||||||
if (fcons)
|
if (fcons)
|
||||||
|
@ -6374,10 +6414,12 @@ Expression* Parser::CoerceExpression(Expression* exp, Declaration* type)
|
||||||
Declaration* fcons = type->mScope ? type->mScope->Lookup(type->mIdent->PreMangle("+")) : nullptr;
|
Declaration* fcons = type->mScope ? type->mScope->Lookup(type->mIdent->PreMangle("+")) : nullptr;
|
||||||
if (fcons)
|
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)))
|
while (fcons && !(fcons->mBase->mParams && fcons->mBase->mParams->mNext && !fcons->mBase->mParams->mNext->mNext && fcons->mBase->mParams->mNext->mBase->CanAssign(tdec)))
|
||||||
fcons = fcons->mNext;
|
fcons = fcons->mNext;
|
||||||
|
|
||||||
if (fcons)
|
if (fcons)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
Declaration* vdec = AllocTempVar(type->ToMutableType());
|
Declaration* vdec = AllocTempVar(type->ToMutableType());
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -6399,7 +6441,6 @@ Expression* Parser::CoerceExpression(Expression* exp, Declaration* type)
|
||||||
|
|
||||||
Expression* fexp = new Expression(mScanner->mLocation, EX_CALL);
|
Expression* fexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||||
fexp->mLeft = cexp;
|
fexp->mLeft = cexp;
|
||||||
|
|
||||||
fexp->mRight = exp;
|
fexp->mRight = exp;
|
||||||
|
|
||||||
Expression* texp = new Expression(mScanner->mLocation, EX_PREFIX);
|
Expression* texp = new Expression(mScanner->mLocation, EX_PREFIX);
|
||||||
|
@ -6415,6 +6456,8 @@ Expression* Parser::CoerceExpression(Expression* exp, Declaration* type)
|
||||||
lexp->mRight = fexp->mRight;
|
lexp->mRight = fexp->mRight;
|
||||||
fexp->mRight = lexp;
|
fexp->mRight = lexp;
|
||||||
|
|
||||||
|
fexp = ResolveOverloadCall(fexp);
|
||||||
|
|
||||||
Expression* dexp = nullptr;
|
Expression* dexp = nullptr;
|
||||||
if (type->mDestructor)
|
if (type->mDestructor)
|
||||||
{
|
{
|
||||||
|
@ -6558,7 +6601,7 @@ Expression * Parser::ResolveOverloadCall(Expression* exp, Expression* exp2)
|
||||||
fdec = exp->mLeft->mDecValue;
|
fdec = exp->mLeft->mDecValue;
|
||||||
while (fdec)
|
while (fdec)
|
||||||
{
|
{
|
||||||
int d = OverloadDistance(exp->mLeft->mDecValue, exp->mRight);
|
int d = OverloadDistance(fdec, exp->mRight);
|
||||||
fdec = fdec->mNext;
|
fdec = fdec->mNext;
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
mErrors->Error(exp->mLocation, ERRO_AMBIGUOUS_FUNCTION_CALL, "Ambiguous function call", exp->mLeft->mDecValue->mQualIdent);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
assert(dbest);
|
||||||
|
|
||||||
exp->mLeft->mDecValue = dbest;
|
exp->mLeft->mDecValue = dbest;
|
||||||
exp->mLeft->mDecType = dbest->mBase;
|
exp->mLeft->mDecType = dbest->mBase;
|
||||||
exp->mDecType = dbest->mBase->mBase;
|
exp->mDecType = dbest->mBase->mBase;
|
||||||
|
@ -6838,9 +6883,13 @@ Expression* Parser::ParsePostfixExpression(bool lhs)
|
||||||
}
|
}
|
||||||
|
|
||||||
nexp = ResolveOverloadCall(nexp);
|
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)
|
if (parentCall)
|
||||||
exp->mDecType->mFlags |= DTF_STACKCALL;
|
exp->mDecType->mFlags |= DTF_STACKCALL;
|
||||||
|
@ -9372,7 +9421,7 @@ Expression* Parser::ParseSwitchStatement(void)
|
||||||
return sexp;
|
return sexp;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Parser::ExpansionDistance(Declaration* tdec, Declaration* spec)
|
int Parser::ExpansionDistance(Declaration* tdec, Declaration* spec, Declaration* xtdec)
|
||||||
{
|
{
|
||||||
Declaration* ptdec = tdec->mParams;
|
Declaration* ptdec = tdec->mParams;
|
||||||
Declaration* psdec = spec->mParams;
|
Declaration* psdec = spec->mParams;
|
||||||
|
@ -9386,20 +9435,33 @@ int Parser::ExpansionDistance(Declaration* tdec, Declaration* spec)
|
||||||
if (ptdec->mType == DT_CONST_TEMPLATE && psdec->mType == DT_CONST_TEMPLATE)
|
if (ptdec->mType == DT_CONST_TEMPLATE && psdec->mType == DT_CONST_TEMPLATE)
|
||||||
{
|
{
|
||||||
if (ptdec->mBase)
|
if (ptdec->mBase)
|
||||||
|
{
|
||||||
|
if (ptdec->mBase->mType == DT_CONST_INTEGER)
|
||||||
{
|
{
|
||||||
if (ptdec->mBase->mInteger != psdec->mBase->mInteger)
|
if (ptdec->mBase->mInteger != psdec->mBase->mInteger)
|
||||||
return NOOVERLOAD;
|
return NOOVERLOAD;
|
||||||
}
|
}
|
||||||
else
|
else if (ptdec->mBase->mType == DT_CONST_TEMPLATE)
|
||||||
|
{
|
||||||
|
Declaration* pdec = xtdec->mScope->Insert(ptdec->mBase->mIdent, psdec->mBase);
|
||||||
cost += 100;
|
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)
|
else if (ptdec->mType == DT_TYPE_TEMPLATE && psdec->mType == DT_TYPE_TEMPLATE)
|
||||||
{
|
{
|
||||||
if (ptdec->mBase)
|
if (ptdec->mBase)
|
||||||
{
|
{
|
||||||
if (!ptdec->mBase->IsSame(psdec->mBase))
|
if (!xtdec->ResolveTemplate(psdec->mBase, ptdec->mBase))
|
||||||
return NOOVERLOAD;
|
return NOOVERLOAD;
|
||||||
}
|
}
|
||||||
|
else if (!xtdec->ResolveTemplate(psdec->mBase, ptdec))
|
||||||
|
return NOOVERLOAD;
|
||||||
else
|
else
|
||||||
cost += 100;
|
cost += 100;
|
||||||
}
|
}
|
||||||
|
@ -9422,6 +9484,9 @@ int Parser::ExpansionDistance(Declaration* tdec, Declaration* spec)
|
||||||
}
|
}
|
||||||
else if (psdec->mBase)
|
else if (psdec->mBase)
|
||||||
{
|
{
|
||||||
|
if (!xtdec->ResolveTemplate(psdec->mBase, ptdec))
|
||||||
|
return NOOVERLOAD;
|
||||||
|
|
||||||
Declaration* dec = psdec->mBase->mParams;
|
Declaration* dec = psdec->mBase->mParams;
|
||||||
while (dec)
|
while (dec)
|
||||||
{
|
{
|
||||||
|
@ -9437,6 +9502,14 @@ int Parser::ExpansionDistance(Declaration* tdec, Declaration* spec)
|
||||||
ptdec = ptdec->mBase->mParams;
|
ptdec = ptdec->mBase->mParams;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
else if (psdec->mBase)
|
||||||
|
{
|
||||||
|
if (!xtdec->ResolveTemplate(psdec->mBase, ptdec))
|
||||||
|
return NOOVERLOAD;
|
||||||
|
psdec = psdec->mNext;
|
||||||
|
cost += 200;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while (psdec)
|
while (psdec)
|
||||||
|
@ -9471,56 +9544,24 @@ int Parser::ExpansionDistance(Declaration* tdec, Declaration* spec)
|
||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* expd)
|
void Parser::ParseTemplateArguments(Declaration* tmpld, Declaration* tdec)
|
||||||
{
|
|
||||||
Declaration * tdec = new Declaration(mScanner->mLocation, DT_TEMPLATE);
|
|
||||||
tdec->mScope = new DeclarationScope(nullptr, SLEVEL_TEMPLATE);
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
if (expd)
|
|
||||||
{
|
|
||||||
if (tmpld->mBase->mType == DT_TEMPLATE)
|
|
||||||
{
|
|
||||||
Parser* p = tmpld->mBase->mParser->Clone();
|
|
||||||
|
|
||||||
p->mScanner->Replay(tmpld->mBase->mTokens);
|
|
||||||
|
|
||||||
tdec = tmpld->mBase->Clone();
|
|
||||||
tdec->mScope->mName = expd->mScope->mName;
|
|
||||||
tdec->mScope->mParent = expd->mScope;
|
|
||||||
|
|
||||||
p->ParseTemplateDeclarationBody(tdec, nullptr);
|
|
||||||
|
|
||||||
return tdec;
|
|
||||||
}
|
|
||||||
|
|
||||||
Declaration* ppdec = nullptr;
|
|
||||||
Declaration* dec = expd->mParams;
|
|
||||||
|
|
||||||
while (dec)
|
|
||||||
{
|
|
||||||
Declaration* epdec = dec->Clone();
|
|
||||||
|
|
||||||
if (ppdec)
|
|
||||||
ppdec->mNext = epdec;
|
|
||||||
else
|
|
||||||
tdec->mParams = epdec;
|
|
||||||
ppdec = epdec;
|
|
||||||
|
|
||||||
dec = dec->mNext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
ConsumeToken(TK_LESS_THAN);
|
ConsumeToken(TK_LESS_THAN);
|
||||||
|
|
||||||
|
Declaration* tparm = tmpld->mParams;
|
||||||
Declaration* ppdec = nullptr;
|
Declaration* ppdec = nullptr;
|
||||||
|
|
||||||
if (!ConsumeTokenIf(TK_GREATER_THAN))
|
if (!ConsumeTokenIf(TK_GREATER_THAN))
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
Expression* exp = ParseShiftExpression(false);
|
Expression* exp;
|
||||||
|
|
||||||
|
if (tparm && tparm->mType == DT_TYPE_TEMPLATE)
|
||||||
|
exp = ParseSimpleExpression(false, true);
|
||||||
|
else
|
||||||
|
exp = ParseShiftExpression(false);
|
||||||
|
|
||||||
Declaration* pdec = nullptr;
|
Declaration* pdec = nullptr;
|
||||||
|
|
||||||
if (exp->mType == EX_TYPE)
|
if (exp->mType == EX_TYPE)
|
||||||
|
@ -9581,12 +9622,59 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
||||||
ppdec = pdec;
|
ppdec = pdec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tparm)
|
||||||
|
tparm = tparm->mNext;
|
||||||
|
|
||||||
} while (ConsumeTokenIf(TK_COMMA));
|
} while (ConsumeTokenIf(TK_COMMA));
|
||||||
|
|
||||||
ConsumeToken(TK_GREATER_THAN);
|
ConsumeToken(TK_GREATER_THAN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* expd)
|
||||||
|
{
|
||||||
|
Declaration * tdec = new Declaration(mScanner->mLocation, DT_TEMPLATE);
|
||||||
|
tdec->mScope = new DeclarationScope(nullptr, SLEVEL_TEMPLATE);
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
if (expd)
|
||||||
|
{
|
||||||
|
if (tmpld->mBase->mType == DT_TEMPLATE)
|
||||||
|
{
|
||||||
|
Parser* p = tmpld->mBase->mParser->Clone();
|
||||||
|
|
||||||
|
p->mScanner->Replay(tmpld->mBase->mTokens);
|
||||||
|
|
||||||
|
tdec = tmpld->mBase->Clone();
|
||||||
|
tdec->mScope->mName = expd->mScope->mName;
|
||||||
|
tdec->mScope->mParent = expd->mScope;
|
||||||
|
|
||||||
|
p->ParseTemplateDeclarationBody(tdec, nullptr);
|
||||||
|
|
||||||
|
return tdec;
|
||||||
|
}
|
||||||
|
|
||||||
|
Declaration* ppdec = nullptr;
|
||||||
|
Declaration* dec = expd->mParams;
|
||||||
|
|
||||||
|
while (dec)
|
||||||
|
{
|
||||||
|
Declaration* epdec = dec->Clone();
|
||||||
|
|
||||||
|
if (ppdec)
|
||||||
|
ppdec->mNext = epdec;
|
||||||
|
else
|
||||||
|
tdec->mParams = epdec;
|
||||||
|
ppdec = epdec;
|
||||||
|
|
||||||
|
dec = dec->mNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ParseTemplateArguments(tmpld, tdec);
|
||||||
|
}
|
||||||
|
|
||||||
while (!tmpld->mTokens)
|
while (!tmpld->mTokens)
|
||||||
tmpld = tmpld->mNext;
|
tmpld = tmpld->mNext;
|
||||||
|
|
||||||
|
@ -9616,11 +9704,16 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
||||||
Declaration* etdec = nullptr;
|
Declaration* etdec = nullptr;
|
||||||
|
|
||||||
Declaration* dec = tmpld;
|
Declaration* dec = tmpld;
|
||||||
|
Declaration* mxtdec = nullptr;
|
||||||
while (dec)
|
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)
|
if (dist < mindist)
|
||||||
{
|
{
|
||||||
|
mxtdec = xtdec;
|
||||||
mindist = dist;
|
mindist = dist;
|
||||||
etdec = dec;
|
etdec = dec;
|
||||||
}
|
}
|
||||||
|
@ -9635,22 +9728,17 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
||||||
tmpld = etdec;
|
tmpld = etdec;
|
||||||
|
|
||||||
dec = tdec->mParams;
|
dec = tdec->mParams;
|
||||||
Declaration * pdec = tmpld->mParams;
|
Declaration * pdec = tmpld->mBase->mTemplate->mParams;
|
||||||
|
|
||||||
Declaration * ppdec = nullptr;
|
Declaration * ppdec = nullptr;
|
||||||
while (pdec)
|
while (pdec)
|
||||||
{
|
{
|
||||||
|
Declaration* rdec = mxtdec->mScope->Lookup(pdec->mIdent);
|
||||||
if (pdec->mType == DT_PACK_TEMPLATE)
|
if (pdec->mType == DT_PACK_TEMPLATE)
|
||||||
{
|
{
|
||||||
if (!dec)
|
if (!rdec)
|
||||||
{
|
{
|
||||||
Declaration* packd = new Declaration(tdec->mLocation, DT_PACK_TEMPLATE);
|
rdec = new Declaration(tdec->mLocation, DT_PACK_TYPE);
|
||||||
packd->mBase = new Declaration(tdec->mLocation, DT_PACK_TYPE);
|
|
||||||
if (ppdec)
|
|
||||||
ppdec->mNext = packd;
|
|
||||||
else
|
|
||||||
tdec->mParams = packd;
|
|
||||||
dec = packd;
|
|
||||||
}
|
}
|
||||||
else if (dec->mType != DT_PACK_TEMPLATE)
|
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;
|
// rdec->mIdent = pdec->mIdent;
|
||||||
tdec->mScope->Insert(dec->mIdent, dec->mBase);
|
tdec->mScope->Insert(pdec->mIdent, rdec);
|
||||||
|
|
||||||
ppdec = dec;
|
|
||||||
dec = dec->mNext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pdec = pdec->mNext;
|
pdec = pdec->mNext;
|
||||||
|
@ -9871,8 +9956,20 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
||||||
tpthis = tmpld->mClass;
|
tpthis = tmpld->mClass;
|
||||||
else if (expd && expd->mBase)
|
else if (expd && expd->mBase)
|
||||||
tpthis = expd->mBase->BuildConstPointer(tdec->mLocation);
|
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);
|
tdec->mBase = p->ParseDeclaration(nullptr, true, false, tpthis, tdec);
|
||||||
|
|
||||||
|
p->mScope = oscope;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
tdec->mBase = p->ParseDeclaration(nullptr, true, false, tpthis, tdec);
|
||||||
}
|
}
|
||||||
|
|
||||||
p->mTemplateScope = nullptr;
|
p->mTemplateScope = nullptr;
|
||||||
|
@ -10153,6 +10250,20 @@ void Parser::ParseTemplateDeclarationBody(Declaration * tdec, Declaration * pthi
|
||||||
bdec->mQualIdent = mScope->Mangle(mScanner->mTokenIdent);
|
bdec->mQualIdent = mScope->Mangle(mScanner->mTokenIdent);
|
||||||
bdec->mScope = new DeclarationScope(nullptr, SLEVEL_CLASS, bdec->mQualIdent);
|
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)
|
while (mScanner->mToken != TK_SEMICOLON && mScanner->mToken != TK_OPEN_BRACE)
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,8 @@ protected:
|
||||||
void ParseTemplateDeclarationBody(Declaration* tdec, Declaration* pthis);
|
void ParseTemplateDeclarationBody(Declaration* tdec, Declaration* pthis);
|
||||||
Declaration* FunctionAutoParamsToTemplate(Declaration* fdec);
|
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);
|
Declaration* ParseTemplateExpansion(Declaration* tmpld, Declaration* expd);
|
||||||
void CompleteTemplateExpansion(Declaration* tmpld);
|
void CompleteTemplateExpansion(Declaration* tmpld);
|
||||||
|
|
||||||
|
@ -124,7 +125,9 @@ protected:
|
||||||
Expression* ExpandPackExpression(Expression* exp, Expression* pack, Expression* item);
|
Expression* ExpandPackExpression(Expression* exp, Expression* pack, Expression* item);
|
||||||
Expression* ParseBinaryFoldExpression(Expression * exp);
|
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* ParsePrefixExpression(bool lhs);
|
||||||
Expression* ParsePostfixExpression(bool lhs);
|
Expression* ParsePostfixExpression(bool lhs);
|
||||||
Expression* ParseMulExpression(bool lhs);
|
Expression* ParseMulExpression(bool lhs);
|
||||||
|
|
|
@ -130,6 +130,12 @@
|
||||||
}
|
}
|
||||||
"Entry"
|
"Entry"
|
||||||
{
|
{
|
||||||
|
"MsmKey" = "8:_1328E18B9638422795616BABEAAFA600"
|
||||||
|
"OwnerKey" = "8:_UNDEFINED"
|
||||||
|
"MsmSig" = "8:_UNDEFINED"
|
||||||
|
}
|
||||||
|
"Entry"
|
||||||
|
{
|
||||||
"MsmKey" = "8:_1393003825B9451084DB314DD4267AD5"
|
"MsmKey" = "8:_1393003825B9451084DB314DD4267AD5"
|
||||||
"OwnerKey" = "8:_UNDEFINED"
|
"OwnerKey" = "8:_UNDEFINED"
|
||||||
"MsmSig" = "8:_UNDEFINED"
|
"MsmSig" = "8:_UNDEFINED"
|
||||||
|
@ -1801,6 +1807,26 @@
|
||||||
"IsDependency" = "11:FALSE"
|
"IsDependency" = "11:FALSE"
|
||||||
"IsolateTo" = "8:"
|
"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"
|
"{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_1393003825B9451084DB314DD4267AD5"
|
||||||
{
|
{
|
||||||
"SourcePath" = "8:..\\samples\\memmap\\allmem.c"
|
"SourcePath" = "8:..\\samples\\memmap\\allmem.c"
|
||||||
|
@ -6676,7 +6702,7 @@
|
||||||
{
|
{
|
||||||
"{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_FB2E467BC172457785F4279BB0BFE8B6"
|
"{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_FB2E467BC172457785F4279BB0BFE8B6"
|
||||||
{
|
{
|
||||||
"SourcePath" = "8:..\\Releasex64\\oscar64.exe"
|
"SourcePath" = "8:..\\Debugx64\\oscar64.exe"
|
||||||
"TargetName" = "8:"
|
"TargetName" = "8:"
|
||||||
"Tag" = "8:"
|
"Tag" = "8:"
|
||||||
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
"Folder" = "8:_607E75AF0E2A4CB9908C4C39DF8FE6E4"
|
||||||
|
|
Loading…
Reference in New Issue