Fix multi instantiation of inline constructors

This commit is contained in:
drmortalwombat 2023-10-10 09:02:30 +02:00
parent 312914d78c
commit 6a30a38415
8 changed files with 120 additions and 4 deletions

View File

@ -21,6 +21,9 @@ rem @echo off
@call :test opp_pairtest.cpp
@if %errorlevel% neq 0 goto :error
@call :test opp_parts.cpp
@if %errorlevel% neq 0 goto :error
@call :test operatoroverload.cpp
@if %errorlevel% neq 0 goto :error

2
autotest/opp_part1.cpp Normal file
View File

@ -0,0 +1,2 @@
#include "opp_part1.h"

40
autotest/opp_part1.h Normal file
View File

@ -0,0 +1,40 @@
#pragma once
#include <opp/vector.h>
class A
{
protected:
int a, b;
public:
A(int a_, int b_)
: a(a_), b(b_)
{}
int sum(void) const
{
return a * b;
}
};
class AS
{
protected:
opp::vector<A> va;
public:
AS(const opp::vector<A> & v)
: va(v)
{}
int sum(void)
{
int s = 0;
for(const auto & a : va)
s += a.sum();
return s;
}
};
#pragma compile("opp_part1.cpp")

13
autotest/opp_part2.cpp Normal file
View File

@ -0,0 +1,13 @@
#include "opp_part2.h"
BS::BS(const opp::vector<A> & v)
: va(v)
{}
int BS::sum(void)
{
int s = 0;
for(const auto & a : va)
s += a.sum();
return s;
}

16
autotest/opp_part2.h Normal file
View File

@ -0,0 +1,16 @@
#pragma once
#include "opp_part1.h"
class BS
{
protected:
opp::vector<A> va;
public:
BS(const opp::vector<A> & v);
int sum(void);
};
#pragma compile("opp_part2.cpp")

25
autotest/opp_parts.cpp Normal file
View File

@ -0,0 +1,25 @@
#include <assert.h>
#include "opp_part1.h"
#include "opp_part2.h"
int main(void)
{
opp::vector<A> va;
va.push_back(A(1, 2));
va.push_back(A(3, 4));
va.push_back(A(6, 4));
va.push_back(A(0, 9));
AS as(va);
va.push_back(A(7, 1));
BS bs(va);
assert(bs.sum() == 2 + 12 + 24 + 7);
assert(as.sum() == 2 + 12 + 24);
return 0;
}

View File

@ -15997,7 +15997,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
while (i < mInstructions.Size())
{
InterInstruction* ins(mInstructions[i]);
if ((ins->mCode == IC_CALL || ins->mCode == IC_CALL_NATIVE) && ins->mSrc[0].mTemp < 0)
if (ins->mCode == IC_CALL || ins->mCode == IC_CALL_NATIVE)
{
int j = i;
while (j > 0 && CanSwapInstructions(ins, mInstructions[j - 1]) && TempUseDelta(mInstructions[j - 1]) >= 0)
@ -17434,7 +17434,7 @@ void InterCodeProcedure::Close(void)
{
GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "tile_row");
CheckFunc = !strcmp(mIdent->mString, "mod");
mEntryBlock = mBlocks[0];

View File

@ -3879,6 +3879,8 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
pdec = pdec->mNext;
}
Declaration* dec = cdec;
if (pdec)
{
if (!cdec->mBase->IsSame(pdec->mBase))
@ -3903,7 +3905,9 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
}
}
cdec = pdec;
dec = pdec;
if (!(pdec->mFlags & DTF_DEFINED))
cdec = pdec;
}
cdec->mIdent = pthis->mBase->mIdent->PreMangle("+");
@ -3931,7 +3935,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
cdec->mNumVars = mLocalIndex;
}
return cdec;
return dec;
}
if (bdec && bdec->mType == DT_TYPE_STRUCT && ConsumeTokenIf(TK_COLCOLON))
@ -6097,6 +6101,19 @@ Expression* Parser::CoerceExpression(Expression* exp, Declaration* type)
return nexp;
}
}
if (type->mType == DT_TYPE_POINTER && type->mBase->mType == DT_TYPE_FUNCTION)
{
Declaration* fr = tdec->mScope->Lookup(Ident::Unique("operator()"));
if (fr && !(fr->mBase->mFlags & DTF_FUNC_THIS))
{
Expression* nexp = new Expression(exp->mLocation, EX_CONSTANT);
nexp->mDecType = fr->mBase;
nexp->mDecValue = fr;
return nexp;
}
}
}
if (type->mType == DT_TYPE_STRUCT)