Automatic function template expansion
This commit is contained in:
parent
5b7334bb17
commit
cb5451b9b9
|
@ -10,6 +10,19 @@ DeclarationScope::DeclarationScope(DeclarationScope* parent, ScopeLevel level, c
|
||||||
mHash = nullptr;
|
mHash = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeclarationScope::Clear(void)
|
||||||
|
{
|
||||||
|
mHashFill = 0;
|
||||||
|
if (mHash)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < mHashSize; i++)
|
||||||
|
{
|
||||||
|
mHash[i].mDec = nullptr;
|
||||||
|
mHash[i].mIdent = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DeclarationScope::~DeclarationScope(void)
|
DeclarationScope::~DeclarationScope(void)
|
||||||
{
|
{
|
||||||
delete[] mHash;
|
delete[] mHash;
|
||||||
|
@ -797,7 +810,7 @@ Declaration::Declaration(const Location& loc, DecType type)
|
||||||
mConst(nullptr), mMutable(nullptr),
|
mConst(nullptr), mMutable(nullptr),
|
||||||
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),
|
mVTable(nullptr), mTemplate(nullptr),
|
||||||
mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1),
|
mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1),
|
||||||
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)
|
||||||
|
@ -920,6 +933,11 @@ const Ident* Declaration::MangleIdent(void)
|
||||||
else
|
else
|
||||||
mMangleIdent = mQualIdent;
|
mMangleIdent = mQualIdent;
|
||||||
|
|
||||||
|
if (mTemplate)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (mFlags & DTF_CONST)
|
if (mFlags & DTF_CONST)
|
||||||
mMangleIdent = mMangleIdent->PreMangle("const ");
|
mMangleIdent = mMangleIdent->PreMangle("const ");
|
||||||
}
|
}
|
||||||
|
@ -927,44 +945,146 @@ const Ident* Declaration::MangleIdent(void)
|
||||||
return mMangleIdent;
|
return mMangleIdent;
|
||||||
}
|
}
|
||||||
|
|
||||||
Declaration* Declaration::TemplateExpand(Declaration* tdec)
|
bool Declaration::ResolveTemplate(Expression* pexp, Declaration* tdec)
|
||||||
{
|
{
|
||||||
if (mType == DT_ARGUMENT)
|
Declaration* pdec = tdec->mBase->mParams;
|
||||||
|
|
||||||
|
while (pexp)
|
||||||
{
|
{
|
||||||
Declaration* edec = this->Clone();
|
Expression* ex = pexp;
|
||||||
edec->mBase = mBase->TemplateExpand(tdec);
|
if (pexp->mType == EX_LIST)
|
||||||
if (mNext)
|
|
||||||
edec->mNext = mNext->TemplateExpand(tdec);
|
|
||||||
return edec;
|
|
||||||
}
|
|
||||||
else if (mType == DT_CONST_FUNCTION)
|
|
||||||
{
|
{
|
||||||
Declaration* edec = this->Clone();
|
ex = pexp->mLeft;
|
||||||
edec->mBase = mBase->TemplateExpand(tdec);
|
pexp = pexp->mRight;
|
||||||
return edec;
|
|
||||||
}
|
|
||||||
else if (mType == DT_TYPE_FUNCTION)
|
|
||||||
{
|
|
||||||
Declaration* edec = this->Clone();
|
|
||||||
edec->mBase = mBase->TemplateExpand(tdec);
|
|
||||||
if (edec->mParams)
|
|
||||||
edec->mParams = mParams->TemplateExpand(tdec);
|
|
||||||
return edec;
|
|
||||||
}
|
|
||||||
else if (mType == DT_TYPE_TEMPLATE || mType == DT_CONST_TEMPLATE)
|
|
||||||
{
|
|
||||||
return tdec->mScope->Lookup(mIdent);
|
|
||||||
}
|
|
||||||
else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY || mType == DT_TYPE_REFERENCE)
|
|
||||||
{
|
|
||||||
Declaration* edec = this->Clone();
|
|
||||||
edec->mBase = mBase->TemplateExpand(tdec);
|
|
||||||
return edec;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return this;
|
pexp = nullptr;
|
||||||
|
|
||||||
|
if (pdec)
|
||||||
|
{
|
||||||
|
if (!ResolveTemplate(ex->mDecType, pdec->mBase))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
pdec = pdec->mNext;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Declaration* ppdec = nullptr;
|
||||||
|
Declaration* ptdec = tdec->mTemplate->mParams;
|
||||||
|
while (ptdec)
|
||||||
|
{
|
||||||
|
Declaration* pdec = mScope->Lookup(ptdec->mIdent);
|
||||||
|
if (!pdec)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Declaration * epdec = ptdec->Clone();
|
||||||
|
epdec->mBase = pdec;
|
||||||
|
epdec->mFlags |= DTF_DEFINED;
|
||||||
|
|
||||||
|
if (ppdec)
|
||||||
|
ppdec->mNext = epdec;
|
||||||
|
else
|
||||||
|
mParams = epdec;
|
||||||
|
ppdec = epdec;
|
||||||
|
ptdec = ptdec->mNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
mScope->Clear();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Declaration::CanResolveTemplate(Expression* pexp, Declaration* tdec)
|
||||||
|
{
|
||||||
|
Declaration* pdec = tdec->mBase->mParams;
|
||||||
|
|
||||||
|
while (pexp)
|
||||||
|
{
|
||||||
|
Expression* ex = pexp;
|
||||||
|
if (pexp->mType == EX_LIST)
|
||||||
|
{
|
||||||
|
ex = pexp->mLeft;
|
||||||
|
pexp = pexp->mRight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pexp = nullptr;
|
||||||
|
|
||||||
|
if (pdec)
|
||||||
|
{
|
||||||
|
if (!ResolveTemplate(ex->mDecType, pdec->mBase))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
pdec = pdec->mNext;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
|
||||||
|
{
|
||||||
|
if (tdec->IsSame(fdec))
|
||||||
|
return true;
|
||||||
|
else if (tdec->mType == DT_TYPE_FUNCTION)
|
||||||
|
{
|
||||||
|
if (fdec->mType == DT_TYPE_FUNCTION)
|
||||||
|
{
|
||||||
|
if (fdec->mBase)
|
||||||
|
{
|
||||||
|
if (!tdec->mBase || !ResolveTemplate(fdec->mBase, tdec->mBase))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (tdec->mBase)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Declaration* fpdec = fdec->mParams;
|
||||||
|
Declaration* tpdec = tdec->mParams;
|
||||||
|
while (fpdec && tpdec)
|
||||||
|
{
|
||||||
|
if (!ResolveTemplate(fpdec->mBase, tpdec->mBase))
|
||||||
|
return false;
|
||||||
|
fpdec = fpdec->mNext;
|
||||||
|
tpdec = tpdec->mNext;
|
||||||
|
}
|
||||||
|
if (fpdec || tpdec)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (tdec->mType == DT_TYPE_REFERENCE)
|
||||||
|
{
|
||||||
|
if (fdec->mType == DT_TYPE_REFERENCE)
|
||||||
|
return ResolveTemplate(fdec->mBase, tdec->mBase);
|
||||||
|
else
|
||||||
|
return ResolveTemplate(fdec, tdec->mBase);
|
||||||
|
}
|
||||||
|
else if (tdec->mType == DT_TYPE_POINTER)
|
||||||
|
{
|
||||||
|
if (fdec->mType == DT_TYPE_POINTER)
|
||||||
|
return ResolveTemplate(fdec->mBase, tdec->mBase);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (tdec->mType == DT_TYPE_TEMPLATE)
|
||||||
|
{
|
||||||
|
Declaration* pdec = mScope->Insert(tdec->mIdent, fdec);
|
||||||
|
if (pdec && !pdec->IsSame(fdec))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return tdec->CanAssign(fdec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Declaration* Declaration::Clone(void)
|
Declaration* Declaration::Clone(void)
|
||||||
{
|
{
|
||||||
Declaration* ndec = new Declaration(mLocation, mType);
|
Declaration* ndec = new Declaration(mLocation, mType);
|
||||||
|
|
|
@ -136,6 +136,7 @@ public:
|
||||||
Declaration* Lookup(const Ident* ident, ScopeLevel limit = SLEVEL_GLOBAL);
|
Declaration* Lookup(const Ident* ident, ScopeLevel limit = SLEVEL_GLOBAL);
|
||||||
|
|
||||||
void End(const Location & loc);
|
void End(const Location & loc);
|
||||||
|
void Clear(void);
|
||||||
|
|
||||||
void UseScope(DeclarationScope* scope);
|
void UseScope(DeclarationScope* scope);
|
||||||
|
|
||||||
|
@ -250,7 +251,7 @@ public:
|
||||||
Declaration * mBase, * mParams, * mNext, * mPrev, * mConst, * mMutable;
|
Declaration * mBase, * mParams, * mNext, * mPrev, * mConst, * mMutable;
|
||||||
Declaration * mDefaultConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment;
|
Declaration * mDefaultConstructor, * mDestructor, * mCopyConstructor, * mCopyAssignment;
|
||||||
Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment;
|
Declaration * mVectorConstructor, * mVectorDestructor, * mVectorCopyConstructor, * mVectorCopyAssignment;
|
||||||
Declaration * mVTable, * mClass;
|
Declaration * mVTable, * mClass, * mTemplate;
|
||||||
|
|
||||||
Expression* mValue;
|
Expression* mValue;
|
||||||
DeclarationScope* mScope;
|
DeclarationScope* mScope;
|
||||||
|
@ -296,7 +297,9 @@ public:
|
||||||
Declaration* BuildConstPointer(const Location& loc);
|
Declaration* BuildConstPointer(const Location& loc);
|
||||||
Declaration* BuildConstReference(const Location& loc);
|
Declaration* BuildConstReference(const Location& loc);
|
||||||
|
|
||||||
Declaration* TemplateExpand(Declaration* tdec);
|
bool CanResolveTemplate(Expression* pexp, Declaration* tdec);
|
||||||
|
bool ResolveTemplate(Declaration* fdec, Declaration * tdec);
|
||||||
|
bool ResolveTemplate(Expression* pexp, Declaration* tdec);
|
||||||
|
|
||||||
const Ident* MangleIdent(void);
|
const Ident* MangleIdent(void);
|
||||||
|
|
||||||
|
|
|
@ -132,7 +132,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
|
||||||
structName = mScanner->mTokenIdent;
|
structName = mScanner->mTokenIdent;
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
Declaration* edec = mScope->Lookup(structName);
|
Declaration* edec = mScope->Lookup(structName);
|
||||||
if (edec && edec->mType == DT_TEMPLATE)
|
if (edec && edec->mTemplate)
|
||||||
{
|
{
|
||||||
mTemplateScope->Insert(structName, dec);
|
mTemplateScope->Insert(structName, dec);
|
||||||
|
|
||||||
|
@ -596,8 +596,8 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified)
|
||||||
|
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
|
|
||||||
if (dec && dec->mType == DT_TEMPLATE)
|
if (dec && dec->mTemplate)
|
||||||
dec = ParseTemplateExpansion(dec, nullptr);
|
dec = ParseTemplateExpansion(dec->mTemplate, nullptr);
|
||||||
|
|
||||||
while (qualified && dec && dec->mType == DT_TYPE_STRUCT && ConsumeTokenIf(TK_COLCOLON))
|
while (qualified && dec && dec->mType == DT_TYPE_STRUCT && ConsumeTokenIf(TK_COLCOLON))
|
||||||
{
|
{
|
||||||
|
@ -846,7 +846,7 @@ Declaration* Parser::ParsePostfixDeclaration(void)
|
||||||
if (mScanner->mToken == TK_LESS_THAN && mTemplateScope)
|
if (mScanner->mToken == TK_LESS_THAN && mTemplateScope)
|
||||||
{
|
{
|
||||||
Declaration* tdec = mScope->Lookup(dec->mIdent);
|
Declaration* tdec = mScope->Lookup(dec->mIdent);
|
||||||
if (tdec && tdec->mType == DT_TEMPLATE)
|
if (tdec && tdec->mTemplate)
|
||||||
{
|
{
|
||||||
// for now just skip over template stuff
|
// for now just skip over template stuff
|
||||||
while (!ConsumeTokenIf(TK_GREATER_THAN))
|
while (!ConsumeTokenIf(TK_GREATER_THAN))
|
||||||
|
@ -3730,7 +3730,11 @@ 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 (ldec && ldec != pdec)
|
if (ldec && ldec->mTemplate && mTemplateScope)
|
||||||
|
{
|
||||||
|
ndec->mQualIdent = ndec->mQualIdent->Mangle(mTemplateScope->mName->mString);
|
||||||
|
}
|
||||||
|
else 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)
|
||||||
|
@ -4463,8 +4467,8 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
|
||||||
dec = ParseQualIdent();
|
dec = ParseQualIdent();
|
||||||
if (dec)
|
if (dec)
|
||||||
{
|
{
|
||||||
if (dec->mType == DT_TEMPLATE)
|
if (dec->mTemplate && mScanner->mToken == TK_LESS_THAN)
|
||||||
dec = ParseTemplateExpansion(dec, nullptr);
|
dec = ParseTemplateExpansion(dec->mTemplate, nullptr);
|
||||||
|
|
||||||
if (dec->mType == DT_CONST_INTEGER || dec->mType == DT_CONST_FLOAT || dec->mType == DT_CONST_FUNCTION || dec->mType == DT_CONST_ASSEMBLER || dec->mType == DT_LABEL || dec->mType == DT_LABEL_REF)
|
if (dec->mType == DT_CONST_INTEGER || dec->mType == DT_CONST_FLOAT || dec->mType == DT_CONST_FUNCTION || dec->mType == DT_CONST_ASSEMBLER || dec->mType == DT_LABEL || dec->mType == DT_LABEL_REF)
|
||||||
{
|
{
|
||||||
|
@ -4758,7 +4762,17 @@ static const int NOOVERLOAD = 0x7fffffff;
|
||||||
|
|
||||||
int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
|
int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
|
||||||
{
|
{
|
||||||
Declaration* pdec = fdec->mParams;
|
if (fdec->mTemplate)
|
||||||
|
{
|
||||||
|
Declaration* tdec = new Declaration(mScanner->mLocation, DT_TEMPLATE);
|
||||||
|
tdec->mScope = new DeclarationScope(nullptr, SLEVEL_TEMPLATE);
|
||||||
|
if (tdec->CanResolveTemplate(pexp, fdec))
|
||||||
|
return 16;
|
||||||
|
else
|
||||||
|
return NOOVERLOAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
Declaration* pdec = fdec->mBase->mParams;
|
||||||
|
|
||||||
int dist = 0;
|
int dist = 0;
|
||||||
|
|
||||||
|
@ -4884,7 +4898,7 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
|
||||||
|
|
||||||
pdec = pdec->mNext;
|
pdec = pdec->mNext;
|
||||||
}
|
}
|
||||||
else if (fdec->mFlags & DTF_VARIADIC)
|
else if (fdec->mBase->mFlags & DTF_VARIADIC)
|
||||||
{
|
{
|
||||||
dist += 1024;
|
dist += 1024;
|
||||||
break;
|
break;
|
||||||
|
@ -5052,6 +5066,20 @@ Expression* Parser::CoerceExpression(Expression* exp, Declaration* type)
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Parser::ExpandFunctionCallTemplate(Expression* exp)
|
||||||
|
{
|
||||||
|
if (exp->mLeft->mDecValue->mTemplate)
|
||||||
|
{
|
||||||
|
Declaration* tdec = new Declaration(mScanner->mLocation, DT_TEMPLATE);
|
||||||
|
tdec->mScope = new DeclarationScope(nullptr, SLEVEL_TEMPLATE);
|
||||||
|
if (tdec->ResolveTemplate(exp->mRight, exp->mLeft->mDecValue))
|
||||||
|
{
|
||||||
|
exp->mLeft->mDecValue = ParseTemplateExpansion(exp->mLeft->mDecValue->mTemplate, tdec);
|
||||||
|
exp->mLeft->mDecType = exp->mLeft->mDecValue->mBase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Parser::CompleteFunctionDefaultParams(Expression* exp)
|
void Parser::CompleteFunctionDefaultParams(Expression* exp)
|
||||||
{
|
{
|
||||||
Declaration* fdec = exp->mLeft->mDecValue;
|
Declaration* fdec = exp->mLeft->mDecValue;
|
||||||
|
@ -5110,7 +5138,7 @@ Expression * Parser::ResolveOverloadCall(Expression* exp, Expression* exp2)
|
||||||
|
|
||||||
while (fdec)
|
while (fdec)
|
||||||
{
|
{
|
||||||
int d = OverloadDistance(fdec->mBase, exp->mRight);
|
int d = OverloadDistance(fdec, exp->mRight);
|
||||||
if (d < ibest)
|
if (d < ibest)
|
||||||
{
|
{
|
||||||
dbest = fdec;
|
dbest = fdec;
|
||||||
|
@ -5125,7 +5153,7 @@ Expression * Parser::ResolveOverloadCall(Expression* exp, Expression* exp2)
|
||||||
|
|
||||||
while (fdec2)
|
while (fdec2)
|
||||||
{
|
{
|
||||||
int d = OverloadDistance(fdec2->mBase, exp2->mRight);
|
int d = OverloadDistance(fdec2, exp2->mRight);
|
||||||
if (d < ibest)
|
if (d < ibest)
|
||||||
{
|
{
|
||||||
dbest = fdec2;
|
dbest = fdec2;
|
||||||
|
@ -5156,6 +5184,7 @@ Expression * Parser::ResolveOverloadCall(Expression* exp, Expression* exp2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExpandFunctionCallTemplate(exp);
|
||||||
CompleteFunctionDefaultParams(exp);
|
CompleteFunctionDefaultParams(exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7209,9 +7238,9 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
||||||
if (!(mdec->mFlags & DTF_DEFINED))
|
if (!(mdec->mFlags & DTF_DEFINED))
|
||||||
{
|
{
|
||||||
Declaration* mpdec = mScope->Lookup(tmpld->mScope->Mangle(mdec->mIdent));
|
Declaration* mpdec = mScope->Lookup(tmpld->mScope->Mangle(mdec->mIdent));
|
||||||
if (mpdec && mpdec->mType == DT_TEMPLATE)
|
if (mpdec && mpdec->mTemplate)
|
||||||
{
|
{
|
||||||
p->ParseTemplateExpansion(mpdec, tdec);
|
p->ParseTemplateExpansion(mpdec->mTemplate, tdec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7316,6 +7345,7 @@ void Parser::ParseTemplateDeclaration(void)
|
||||||
// Class template
|
// Class template
|
||||||
Declaration* bdec = new Declaration(mScanner->mLocation, DT_TYPE_STRUCT);
|
Declaration* bdec = new Declaration(mScanner->mLocation, DT_TYPE_STRUCT);
|
||||||
tdec->mBase = bdec;
|
tdec->mBase = bdec;
|
||||||
|
bdec->mTemplate = tdec;
|
||||||
|
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
if (mScanner->mToken == TK_IDENT)
|
if (mScanner->mToken == TK_IDENT)
|
||||||
|
@ -7364,6 +7394,7 @@ void Parser::ParseTemplateDeclaration(void)
|
||||||
adec->mFlags |= DTF_NATIVE;
|
adec->mFlags |= DTF_NATIVE;
|
||||||
|
|
||||||
tdec->mBase = adec;
|
tdec->mBase = adec;
|
||||||
|
adec->mTemplate = tdec;
|
||||||
|
|
||||||
if (ConsumeTokenIf(TK_OPEN_BRACE))
|
if (ConsumeTokenIf(TK_OPEN_BRACE))
|
||||||
{
|
{
|
||||||
|
@ -7389,7 +7420,8 @@ void Parser::ParseTemplateDeclaration(void)
|
||||||
tdec->mQualIdent = tdec->mBase->mQualIdent;
|
tdec->mQualIdent = tdec->mBase->mQualIdent;
|
||||||
tdec->mScope->mName = tdec->mQualIdent;
|
tdec->mScope->mName = tdec->mQualIdent;
|
||||||
|
|
||||||
mScope->Insert(tdec->mQualIdent, tdec);
|
mScope->Insert(tdec->mQualIdent, tdec->mBase);
|
||||||
|
mCompilationUnits->mScope->Insert(tdec->mQualIdent, tdec->mBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,7 @@ protected:
|
||||||
Expression* CoerceExpression(Expression* exp, Declaration* type);
|
Expression* CoerceExpression(Expression* exp, Declaration* type);
|
||||||
bool CanCoerceExpression(Expression* exp, Declaration* type);
|
bool CanCoerceExpression(Expression* exp, Declaration* type);
|
||||||
void CompleteFunctionDefaultParams(Expression* exp);
|
void CompleteFunctionDefaultParams(Expression* exp);
|
||||||
|
void ExpandFunctionCallTemplate(Expression* exp);
|
||||||
|
|
||||||
void ParseTemplateDeclaration(void);
|
void ParseTemplateDeclaration(void);
|
||||||
Declaration* ParseTemplateExpansion(Declaration* tmpld, Declaration* expd);
|
Declaration* ParseTemplateExpansion(Declaration* tmpld, Declaration* expd);
|
||||||
|
|
Loading…
Reference in New Issue