mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 12:32:20 +02:00
Fixed some comptime dependency rebuilding issues with aliases/extensions
This commit is contained in:
parent
1cd198cea9
commit
434a7406de
22 changed files with 394 additions and 86 deletions
|
@ -4,28 +4,43 @@
|
||||||
|
|
||||||
NS_BF_BEGIN;
|
NS_BF_BEGIN;
|
||||||
|
|
||||||
#define BF_BITSET_ELEM_SIZE (sizeof(uintptr)*8)
|
#define BF_BITSET_ELEM_BITCOUNT (sizeof(uintptr)*8)
|
||||||
|
|
||||||
class BitSet
|
class BitSet
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
uintptr* mBits;
|
uintptr* mBits;
|
||||||
int mNumInts;
|
int mNumBits;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BitSet()
|
BitSet()
|
||||||
{
|
{
|
||||||
mNumInts = 0;
|
mNumBits = 0;
|
||||||
mBits = NULL;
|
mBits = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
BitSet(int numBits)
|
BitSet(int numBits)
|
||||||
{
|
{
|
||||||
mNumInts = 0;
|
mNumBits = 0;
|
||||||
mBits = NULL;
|
mBits = NULL;
|
||||||
this->Resize(numBits);
|
this->Resize(numBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BitSet(BitSet&& other)
|
||||||
|
{
|
||||||
|
mNumBits = other.mNumBits;
|
||||||
|
mBits = other.mBits;
|
||||||
|
other.mNumBits = 0;
|
||||||
|
other.mBits = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BitSet(const BitSet& other)
|
||||||
|
{
|
||||||
|
mNumBits = 0;
|
||||||
|
mBits = NULL;
|
||||||
|
*this = other;
|
||||||
|
}
|
||||||
|
|
||||||
~BitSet()
|
~BitSet()
|
||||||
{
|
{
|
||||||
delete this->mBits;
|
delete this->mBits;
|
||||||
|
@ -33,28 +48,68 @@ public:
|
||||||
|
|
||||||
void Resize(int numBits)
|
void Resize(int numBits)
|
||||||
{
|
{
|
||||||
int numInts = (numBits + BF_BITSET_ELEM_SIZE - 1) / BF_BITSET_ELEM_SIZE;
|
int numInts = (numBits + BF_BITSET_ELEM_BITCOUNT - 1) / BF_BITSET_ELEM_BITCOUNT;
|
||||||
if (numInts == mNumInts)
|
int curNumInts = (mNumBits + BF_BITSET_ELEM_BITCOUNT - 1) / BF_BITSET_ELEM_BITCOUNT;
|
||||||
return;
|
mNumBits = numBits;
|
||||||
this->mNumInts = numInts;
|
if (numInts == curNumInts)
|
||||||
|
return;
|
||||||
|
this->mNumBits = numBits;
|
||||||
delete this->mBits;
|
delete this->mBits;
|
||||||
this->mBits = new uintptr[numInts];
|
this->mBits = new uintptr[numInts];
|
||||||
memset(this->mBits, 0, numInts * sizeof(uintptr));
|
memset(this->mBits, 0, numInts * sizeof(uintptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsSet(int idx)
|
void Clear()
|
||||||
{
|
{
|
||||||
return (this->mBits[idx / BF_BITSET_ELEM_SIZE] & ((uintptr)1 << (idx % BF_BITSET_ELEM_SIZE))) != 0;
|
int curNumInts = (mNumBits + BF_BITSET_ELEM_BITCOUNT - 1) / BF_BITSET_ELEM_BITCOUNT;
|
||||||
|
memset(mBits, 0, curNumInts * sizeof(uintptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsSet(int idx) const
|
||||||
|
{
|
||||||
|
BF_ASSERT((uintptr)idx < (uintptr)mNumBits);
|
||||||
|
return (this->mBits[idx / BF_BITSET_ELEM_BITCOUNT] & ((uintptr)1 << (idx % BF_BITSET_ELEM_BITCOUNT))) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Set(int idx)
|
void Set(int idx)
|
||||||
{
|
{
|
||||||
this->mBits[idx / BF_BITSET_ELEM_SIZE] |= ((uintptr)1 << (idx % BF_BITSET_ELEM_SIZE));
|
BF_ASSERT((uintptr)idx < (uintptr)mNumBits);
|
||||||
|
this->mBits[idx / BF_BITSET_ELEM_BITCOUNT] |= ((uintptr)1 << (idx % BF_BITSET_ELEM_BITCOUNT));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clear(int idx)
|
void Clear(int idx)
|
||||||
{
|
{
|
||||||
this->mBits[idx / BF_BITSET_ELEM_SIZE] &= ~((uintptr)1 << (idx % BF_BITSET_ELEM_SIZE));
|
BF_ASSERT((uintptr)idx < (uintptr)mNumBits);
|
||||||
|
this->mBits[idx / BF_BITSET_ELEM_BITCOUNT] &= ~((uintptr)1 << (idx % BF_BITSET_ELEM_BITCOUNT));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsEmpty()
|
||||||
|
{
|
||||||
|
return mNumBits == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const BitSet& other) const
|
||||||
|
{
|
||||||
|
int curNumInts = (mNumBits + BF_BITSET_ELEM_BITCOUNT - 1) / BF_BITSET_ELEM_BITCOUNT;
|
||||||
|
if (mNumBits != other.mNumBits)
|
||||||
|
return false;
|
||||||
|
for (int i = 0; i < curNumInts; i++)
|
||||||
|
if (mBits[i] != other.mBits[i])
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const BitSet& other) const
|
||||||
|
{
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
BitSet& operator=(const BitSet& other)
|
||||||
|
{
|
||||||
|
Resize(other.mNumBits);
|
||||||
|
int curNumInts = (mNumBits + BF_BITSET_ELEM_BITCOUNT - 1) / BF_BITSET_ELEM_BITCOUNT;
|
||||||
|
memcpy(mBits, other.mBits, curNumInts * sizeof(uintptr));
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
5
IDE/Tests/BugW008/BeefProj.toml
Normal file
5
IDE/Tests/BugW008/BeefProj.toml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
FileVersion = 1
|
||||||
|
|
||||||
|
[Project]
|
||||||
|
Name = "Bug"
|
||||||
|
StartupObject = "Bug.Program"
|
6
IDE/Tests/BugW008/BeefSpace.toml
Normal file
6
IDE/Tests/BugW008/BeefSpace.toml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
FileVersion = 1
|
||||||
|
Projects = {Bug = {Path = "."}}
|
||||||
|
|
||||||
|
[Workspace]
|
||||||
|
StartupProject = "Bug"
|
||||||
|
|
15
IDE/Tests/BugW008/scripts/Test.txt
Normal file
15
IDE/Tests/BugW008/scripts/Test.txt
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# This tests that comptime changes to generic passed extension constraints rebuilds dependencies
|
||||||
|
|
||||||
|
ShowFile("src/Program.bf")
|
||||||
|
GotoText("//End")
|
||||||
|
ToggleBreakpoint()
|
||||||
|
RunWithCompiling()
|
||||||
|
AssertEvalEquals("val", "1")
|
||||||
|
StopRunning()
|
||||||
|
|
||||||
|
ShowFile("src/Gen.bf")
|
||||||
|
ToggleCommentAt("Void")
|
||||||
|
ToggleCommentAt("String")
|
||||||
|
RunWithCompiling()
|
||||||
|
AssertEvalEquals("val", "2")
|
||||||
|
StopRunning()
|
18
IDE/Tests/BugW008/src/Gen.bf
Normal file
18
IDE/Tests/BugW008/src/Gen.bf
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Bug
|
||||||
|
{
|
||||||
|
class Gen
|
||||||
|
{
|
||||||
|
public static Type Get()
|
||||||
|
{
|
||||||
|
//*Void
|
||||||
|
return typeof(void);
|
||||||
|
/*@*/
|
||||||
|
|
||||||
|
/*String
|
||||||
|
return typeof(String);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
IDE/Tests/BugW008/src/Program.bf
Normal file
34
IDE/Tests/BugW008/src/Program.bf
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#pragma warning disable 168
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace Bug
|
||||||
|
{
|
||||||
|
class Zonk<T>
|
||||||
|
{
|
||||||
|
public int Call(float val)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Zonk<T> where comptype(Gen.Get()) : String
|
||||||
|
{
|
||||||
|
public int Call(int val)
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
public static int Main(String[] args)
|
||||||
|
{
|
||||||
|
Zonk<int> zk = scope .();
|
||||||
|
int val = zk.Call(1);
|
||||||
|
//End
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
5
IDE/Tests/BugW009/BeefProj.toml
Normal file
5
IDE/Tests/BugW009/BeefProj.toml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
FileVersion = 1
|
||||||
|
|
||||||
|
[Project]
|
||||||
|
Name = "Bug"
|
||||||
|
StartupObject = "Bug.Program"
|
6
IDE/Tests/BugW009/BeefSpace.toml
Normal file
6
IDE/Tests/BugW009/BeefSpace.toml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
FileVersion = 1
|
||||||
|
Projects = {Bug = {Path = "."}}
|
||||||
|
|
||||||
|
[Workspace]
|
||||||
|
StartupProject = "Bug"
|
||||||
|
|
15
IDE/Tests/BugW009/scripts/Test.txt
Normal file
15
IDE/Tests/BugW009/scripts/Test.txt
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# This tests that comptime alias changes rebuild dependent types
|
||||||
|
|
||||||
|
ShowFile("src/Program.bf")
|
||||||
|
GotoText("//End")
|
||||||
|
ToggleBreakpoint()
|
||||||
|
RunWithCompiling()
|
||||||
|
AssertEvalEquals("val", "1")
|
||||||
|
StopRunning()
|
||||||
|
|
||||||
|
ShowFile("src/Gen.bf")
|
||||||
|
ToggleCommentAt("ClassA")
|
||||||
|
ToggleCommentAt("ClassB")
|
||||||
|
RunWithCompiling()
|
||||||
|
AssertEvalEquals("val", "2")
|
||||||
|
StopRunning()
|
18
IDE/Tests/BugW009/src/Gen.bf
Normal file
18
IDE/Tests/BugW009/src/Gen.bf
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Bug
|
||||||
|
{
|
||||||
|
class Gen
|
||||||
|
{
|
||||||
|
public static Type Get()
|
||||||
|
{
|
||||||
|
//*ClassA
|
||||||
|
return typeof(ClassA);
|
||||||
|
/*@*/
|
||||||
|
|
||||||
|
/*ClassB
|
||||||
|
return typeof(ClassB);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
42
IDE/Tests/BugW009/src/Program.bf
Normal file
42
IDE/Tests/BugW009/src/Program.bf
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#pragma warning disable 168
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace Bug
|
||||||
|
{
|
||||||
|
class ClassA
|
||||||
|
{
|
||||||
|
public int Call()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClassB
|
||||||
|
{
|
||||||
|
public int Call()
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typealias Alias1 = comptype(Gen.Get());
|
||||||
|
typealias Alias2 = Alias1;
|
||||||
|
|
||||||
|
class Zonk<T> : Alias2
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
public static int Main(String[] args)
|
||||||
|
{
|
||||||
|
Zonk<int> zk = scope .();
|
||||||
|
int val = zk.Call();
|
||||||
|
//End
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7012,47 +7012,58 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
||||||
mStats.mTypesQueued += (int)mContext->mPopulateTypeWorkList.size();
|
mStats.mTypesQueued += (int)mContext->mPopulateTypeWorkList.size();
|
||||||
mStats.mMethodsQueued += (int)mContext->mMethodWorkList.size();
|
mStats.mMethodsQueued += (int)mContext->mMethodWorkList.size();
|
||||||
|
|
||||||
//
|
while (true)
|
||||||
{
|
|
||||||
if (mBfObjectTypeDef != NULL)
|
|
||||||
mContext->mScratchModule->ResolveTypeDef(mBfObjectTypeDef, BfPopulateType_Full);
|
|
||||||
|
|
||||||
mContext->RemapObject();
|
|
||||||
|
|
||||||
mSystem->CheckLockYield();
|
|
||||||
|
|
||||||
mWantsDeferMethodDecls = mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_AlwaysInclude;
|
|
||||||
|
|
||||||
CompileReified();
|
|
||||||
mWantsDeferMethodDecls = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
BpLeave();
|
|
||||||
BpEnter("Compile_End");
|
|
||||||
|
|
||||||
{
|
{
|
||||||
BP_ZONE("ProcessingLiveness");
|
//
|
||||||
|
|
||||||
for (auto type : mContext->mResolvedTypes)
|
|
||||||
{
|
|
||||||
auto depType = type->ToDependedType();
|
|
||||||
if (depType != NULL)
|
|
||||||
depType->mRebuildFlags = (BfTypeRebuildFlags)(depType->mRebuildFlags | BfTypeRebuildFlag_AwaitingReference);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool didWork = false;
|
|
||||||
UpdateDependencyMap(mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_ResolveUnused, didWork);
|
|
||||||
|
|
||||||
if (mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_AlwaysInclude)
|
|
||||||
{
|
{
|
||||||
// If UpdateDependencyMap caused methods to be reified, then we need to run PopulateReified again-
|
if (mBfObjectTypeDef != NULL)
|
||||||
// because those methods may be virtual and we need to reify overrides (for example).
|
mContext->mScratchModule->ResolveTypeDef(mBfObjectTypeDef, BfPopulateType_Full);
|
||||||
// We use the DoWorkLoop result to determine if there were actually any changes from UpdateDependencyMap
|
|
||||||
if (didWork)
|
mContext->RemapObject();
|
||||||
|
|
||||||
|
mSystem->CheckLockYield();
|
||||||
|
|
||||||
|
mWantsDeferMethodDecls = mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_AlwaysInclude;
|
||||||
|
|
||||||
|
CompileReified();
|
||||||
|
mWantsDeferMethodDecls = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BpLeave();
|
||||||
|
BpEnter("Compile_End");
|
||||||
|
|
||||||
|
mContext->mHasReifiedQueuedRebuildTypes = false;
|
||||||
|
|
||||||
|
//
|
||||||
|
{
|
||||||
|
BP_ZONE("ProcessingLiveness");
|
||||||
|
|
||||||
|
for (auto type : mContext->mResolvedTypes)
|
||||||
{
|
{
|
||||||
PopulateReified();
|
auto depType = type->ToDependedType();
|
||||||
|
if (depType != NULL)
|
||||||
|
depType->mRebuildFlags = (BfTypeRebuildFlags)(depType->mRebuildFlags | BfTypeRebuildFlag_AwaitingReference);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
bool didWork = false;
|
||||||
|
UpdateDependencyMap(mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_ResolveUnused, didWork);
|
||||||
|
|
||||||
|
if (mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_AlwaysInclude)
|
||||||
|
{
|
||||||
|
// If UpdateDependencyMap caused methods to be reified, then we need to run PopulateReified again-
|
||||||
|
// because those methods may be virtual and we need to reify overrides (for example).
|
||||||
|
// We use the DoWorkLoop result to determine if there were actually any changes from UpdateDependencyMap
|
||||||
|
if (didWork)
|
||||||
|
{
|
||||||
|
PopulateReified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mContext->mHasReifiedQueuedRebuildTypes)
|
||||||
|
break;
|
||||||
|
|
||||||
|
BfLogSysM("DoCompile looping over CompileReified due to mHasReifiedQueuedRebuildTypes\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessPurgatory(true);
|
ProcessPurgatory(true);
|
||||||
|
|
|
@ -77,7 +77,8 @@ BfContext::BfContext(BfCompiler* compiler) :
|
||||||
|
|
||||||
mValueTypeDeinitSentinel = (BfMethodInstance*)1;
|
mValueTypeDeinitSentinel = (BfMethodInstance*)1;
|
||||||
|
|
||||||
mCurStringObjectPoolId = 0;
|
mCurStringObjectPoolId = 0;
|
||||||
|
mHasReifiedQueuedRebuildTypes = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfReportMemory();
|
void BfReportMemory();
|
||||||
|
@ -945,6 +946,9 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeInst->mIsReified)
|
||||||
|
mHasReifiedQueuedRebuildTypes = true;
|
||||||
|
|
||||||
typeInst->mRebuildFlags = (BfTypeRebuildFlags)(typeInst->mRebuildFlags & ~BfTypeRebuildFlag_AddedToWorkList);
|
typeInst->mRebuildFlags = (BfTypeRebuildFlags)(typeInst->mRebuildFlags & ~BfTypeRebuildFlag_AddedToWorkList);
|
||||||
|
|
||||||
bool addToWorkList = true;
|
bool addToWorkList = true;
|
||||||
|
@ -1131,8 +1135,8 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild
|
||||||
genericTypeInstance->mGenericTypeInfo->mGenericParams.Clear();
|
genericTypeInstance->mGenericTypeInfo->mGenericParams.Clear();
|
||||||
genericTypeInstance->mGenericTypeInfo->mValidatedGenericConstraints = false;
|
genericTypeInstance->mGenericTypeInfo->mValidatedGenericConstraints = false;
|
||||||
genericTypeInstance->mGenericTypeInfo->mHadValidateErrors = false;
|
genericTypeInstance->mGenericTypeInfo->mHadValidateErrors = false;
|
||||||
delete genericTypeInstance->mGenericTypeInfo->mGenericExtensionInfo;
|
if (genericTypeInstance->mGenericTypeInfo->mGenericExtensionInfo != NULL)
|
||||||
genericTypeInstance->mGenericTypeInfo->mGenericExtensionInfo = NULL;
|
genericTypeInstance->mGenericTypeInfo->mGenericExtensionInfo->Clear();
|
||||||
genericTypeInstance->mGenericTypeInfo->mProjectsReferenced.Clear();
|
genericTypeInstance->mGenericTypeInfo->mProjectsReferenced.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1182,6 +1186,22 @@ void BfContext::RebuildDependentTypes(BfDependedType* dType)
|
||||||
TypeMethodSignaturesChanged(typeInst);
|
TypeMethodSignaturesChanged(typeInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfContext::RebuildDependentTypes_MidCompile(BfDependedType* dType, const String& reason)
|
||||||
|
{
|
||||||
|
dType->mRebuildFlags = (BfTypeRebuildFlags)(dType->mRebuildFlags | BfTypeRebuildFlag_ChangedMidCompile);
|
||||||
|
int prevDeletedTypes = mCompiler->mStats.mTypesDeleted;
|
||||||
|
if (mCompiler->mIsResolveOnly)
|
||||||
|
mCompiler->mNeedsFullRefresh = true;
|
||||||
|
BfLogSysM("Rebuilding dependent types MidCompile Type:%p Reason:%s\n", dType, reason.c_str());
|
||||||
|
RebuildDependentTypes(dType);
|
||||||
|
|
||||||
|
if (mCompiler->mStats.mTypesDeleted != prevDeletedTypes)
|
||||||
|
{
|
||||||
|
BfLogSysM("Rebuilding dependent types MidCompile Type:%p Reason:%s - updating after deleting types\n", dType, reason.c_str());
|
||||||
|
UpdateAfterDeletingTypes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Dependencies cascade as such:
|
// Dependencies cascade as such:
|
||||||
// DerivedFrom / StructMemberData: these change the layout of memory for the dependent classes,
|
// DerivedFrom / StructMemberData: these change the layout of memory for the dependent classes,
|
||||||
// so not only do the dependent classes need to be rebuild, but any other classes relying on those derived classes
|
// so not only do the dependent classes need to be rebuild, but any other classes relying on those derived classes
|
||||||
|
@ -1254,7 +1274,7 @@ void BfContext::TypeDataChanged(BfDependedType* dType, bool isNonStaticDataChang
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dependentType->mRevision != mCompiler->mRevision)
|
if (dependentType->mRevision != mCompiler->mRevision)
|
||||||
{
|
{
|
||||||
// We need to include DependencyFlag_ParamOrReturnValue because it could be a struct that changes its splatting ability
|
// We need to include DependencyFlag_ParamOrReturnValue because it could be a struct that changes its splatting ability
|
||||||
// We can't ONLY check against structs, though, because a type could change from a class to a struct
|
// We can't ONLY check against structs, though, because a type could change from a class to a struct
|
||||||
if (dependencyFlags &
|
if (dependencyFlags &
|
||||||
|
@ -1264,6 +1284,12 @@ void BfContext::TypeDataChanged(BfDependedType* dType, bool isNonStaticDataChang
|
||||||
{
|
{
|
||||||
RebuildType(dependentType);
|
RebuildType(dependentType);
|
||||||
}
|
}
|
||||||
|
else if (((dependencyFlags & BfDependencyMap::DependencyFlag_NameReference) != 0) &&
|
||||||
|
((dType->mRebuildFlags & BfTypeRebuildFlag_ChangedMidCompile) != 0) &&
|
||||||
|
(dType->IsTypeAlias()))
|
||||||
|
{
|
||||||
|
RebuildType(dependentType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1276,7 +1302,7 @@ void BfContext::TypeDataChanged(BfDependedType* dType, bool isNonStaticDataChang
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dType->mRevision != mCompiler->mRevision)
|
if (dType->mRevision != mCompiler->mRevision)
|
||||||
RebuildType(dType);
|
RebuildType(dType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -351,7 +351,7 @@ class BfContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CritSect mCritSect;
|
CritSect mCritSect;
|
||||||
bool mDeleting;
|
bool mDeleting;
|
||||||
|
|
||||||
BfTypeState* mCurTypeState;
|
BfTypeState* mCurTypeState;
|
||||||
BfSizedArray<BfNamespaceDeclaration*>* mCurNamespaceNodes;
|
BfSizedArray<BfNamespaceDeclaration*>* mCurNamespaceNodes;
|
||||||
|
@ -397,6 +397,7 @@ public:
|
||||||
WorkQueue<BfTypeRefVerifyRequest> mTypeRefVerifyWorkList;
|
WorkQueue<BfTypeRefVerifyRequest> mTypeRefVerifyWorkList;
|
||||||
PtrWorkQueue<BfModule*> mFinishedSlotAwaitModuleWorkList;
|
PtrWorkQueue<BfModule*> mFinishedSlotAwaitModuleWorkList;
|
||||||
PtrWorkQueue<BfModule*> mFinishedModuleWorkList;
|
PtrWorkQueue<BfModule*> mFinishedModuleWorkList;
|
||||||
|
bool mHasReifiedQueuedRebuildTypes;
|
||||||
|
|
||||||
Array<BfGenericParamType*> mGenericParamTypes[3];
|
Array<BfGenericParamType*> mGenericParamTypes[3];
|
||||||
|
|
||||||
|
@ -475,6 +476,7 @@ public:
|
||||||
void ValidateDependencies();
|
void ValidateDependencies();
|
||||||
void RebuildType(BfType* type, bool deleteOnDemandTypes = true, bool rebuildModule = true, bool placeSpecializiedInPurgatory = true);
|
void RebuildType(BfType* type, bool deleteOnDemandTypes = true, bool rebuildModule = true, bool placeSpecializiedInPurgatory = true);
|
||||||
void RebuildDependentTypes(BfDependedType* dType);
|
void RebuildDependentTypes(BfDependedType* dType);
|
||||||
|
void RebuildDependentTypes_MidCompile(BfDependedType* dType, const String& reason);
|
||||||
void TypeDataChanged(BfDependedType* dType, bool isNonStaticDataChange);
|
void TypeDataChanged(BfDependedType* dType, bool isNonStaticDataChange);
|
||||||
void TypeMethodSignaturesChanged(BfTypeInstance* typeInst);
|
void TypeMethodSignaturesChanged(BfTypeInstance* typeInst);
|
||||||
void TypeInlineMethodInternalsChanged(BfTypeInstance* typeInst);
|
void TypeInlineMethodInternalsChanged(BfTypeInstance* typeInst);
|
||||||
|
|
|
@ -1746,7 +1746,11 @@ String BfIRBuilder::ToString(BfIRValue irValue)
|
||||||
auto typeofConst = (BfTypeOf_WithData_Const*)constant;
|
auto typeofConst = (BfTypeOf_WithData_Const*)constant;
|
||||||
return "typeof_withData " + mModule->TypeToString(typeofConst->mType);
|
return "typeof_withData " + mModule->TypeToString(typeofConst->mType);
|
||||||
}
|
}
|
||||||
|
else if (constant->mConstType == BfConstType_Undef)
|
||||||
|
{
|
||||||
|
auto constUndef = (BfConstantUndef*)constant;
|
||||||
|
return "undef " + ToString(constUndef->mType);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BF_FATAL("Unhandled");
|
BF_FATAL("Unhandled");
|
||||||
|
|
|
@ -1258,7 +1258,7 @@ void BfModule::StartNewRevision(RebuildKind rebuildKind, bool force)
|
||||||
mHadBuildError = false;
|
mHadBuildError = false;
|
||||||
mHadBuildWarning = false;
|
mHadBuildWarning = false;
|
||||||
mExtensionCount = 0;
|
mExtensionCount = 0;
|
||||||
mRevision = mCompiler->mRevision;
|
mRevision = mCompiler->mRevision;
|
||||||
mRebuildIdx++;
|
mRebuildIdx++;
|
||||||
ClearModuleData(!force);
|
ClearModuleData(!force);
|
||||||
|
|
||||||
|
|
|
@ -1775,7 +1775,7 @@ public:
|
||||||
void ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* typeInst, BfCEOnCompileKind onCompileKind, bool underlyingTypeDeferred);
|
void ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* typeInst, BfCEOnCompileKind onCompileKind, bool underlyingTypeDeferred);
|
||||||
void DoCEEmit(BfTypeInstance* typeInstance, bool& hadNewMembers, bool underlyingTypeDeferred);
|
void DoCEEmit(BfTypeInstance* typeInstance, bool& hadNewMembers, bool underlyingTypeDeferred);
|
||||||
void DoCEEmit(BfMethodInstance* methodInstance);
|
void DoCEEmit(BfMethodInstance* methodInstance);
|
||||||
void DoPopulateType_TypeAlias(BfTypeInstance* typeAlias);
|
void DoPopulateType_TypeAlias(BfTypeAliasType* typeAlias);
|
||||||
void DoPopulateType_InitSearches(BfTypeInstance* typeInstance);
|
void DoPopulateType_InitSearches(BfTypeInstance* typeInstance);
|
||||||
void DoPopulateType_SetGenericDependencies(BfTypeInstance* genericTypeInstance);
|
void DoPopulateType_SetGenericDependencies(BfTypeInstance* genericTypeInstance);
|
||||||
void DoPopulateType_FinishEnum(BfTypeInstance* typeInstance, bool underlyingTypeDeferred, HashContext* dataMemberHashCtx, BfType* unionInnerType);
|
void DoPopulateType_FinishEnum(BfTypeInstance* typeInstance, bool underlyingTypeDeferred, HashContext* dataMemberHashCtx, BfType* unionInnerType);
|
||||||
|
|
|
@ -184,6 +184,21 @@ bool BfModule::FinishGenericParams(BfType* resolvedTypeRef)
|
||||||
|
|
||||||
if (!typeDef->mPartials.empty())
|
if (!typeDef->mPartials.empty())
|
||||||
{
|
{
|
||||||
|
BitSet prevConstraintsPassedSet;
|
||||||
|
|
||||||
|
if (!genericTypeInst->IsUnspecializedType())
|
||||||
|
{
|
||||||
|
if (genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo != NULL)
|
||||||
|
{
|
||||||
|
auto genericExtensionInfo = genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo;
|
||||||
|
prevConstraintsPassedSet = genericExtensionInfo->mConstraintsPassedSet;
|
||||||
|
genericExtensionInfo->mConstraintsPassedSet.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int extensionCount = 0;
|
||||||
|
|
||||||
|
BfLogSysM("BfModule::FinishGenericParams %p\n", resolvedTypeRef);
|
||||||
for (auto partialTypeDef : typeDef->mPartials)
|
for (auto partialTypeDef : typeDef->mPartials)
|
||||||
{
|
{
|
||||||
if (!partialTypeDef->IsExtension())
|
if (!partialTypeDef->IsExtension())
|
||||||
|
@ -222,6 +237,13 @@ bool BfModule::FinishGenericParams(BfType* resolvedTypeRef)
|
||||||
auto genericExEntry = BuildGenericExtensionInfo(genericTypeInst, partialTypeDef);
|
auto genericExEntry = BuildGenericExtensionInfo(genericTypeInst, partialTypeDef);
|
||||||
if (genericExEntry == NULL)
|
if (genericExEntry == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
auto genericExtensionInfo = genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo;
|
||||||
|
if (extensionCount == 0)
|
||||||
|
genericExtensionInfo->mConstraintsPassedSet.Resize(typeDef->mPartials.mSize);
|
||||||
|
|
||||||
|
extensionCount++;
|
||||||
|
|
||||||
if (!genericTypeInst->IsUnspecializedType())
|
if (!genericTypeInst->IsUnspecializedType())
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
|
SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
|
||||||
|
@ -249,7 +271,18 @@ bool BfModule::FinishGenericParams(BfType* resolvedTypeRef)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (genericExEntry->mConstraintsPassed)
|
||||||
|
genericExtensionInfo->mConstraintsPassedSet.Set(partialTypeDef->mPartialIdx);
|
||||||
|
|
||||||
|
BfLogSysM("BfModule::FinishGenericParams %p partialTypeDef:%p passed:%d\n", resolvedTypeRef, partialTypeDef, genericExEntry->mConstraintsPassed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto genericExtensionInfo = genericTypeInst->mGenericTypeInfo->mGenericExtensionInfo;
|
||||||
|
if ((extensionCount > 0) && (!prevConstraintsPassedSet.IsEmpty()) && (genericExtensionInfo->mConstraintsPassedSet != prevConstraintsPassedSet))
|
||||||
|
{
|
||||||
|
mContext->RebuildDependentTypes_MidCompile(genericTypeInst, "mConstraintsPassedSet changed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1224,7 +1257,8 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
|
||||||
if (resolvedTypeRef->IsTypeAlias())
|
if (resolvedTypeRef->IsTypeAlias())
|
||||||
{
|
{
|
||||||
// Always populate these all the way
|
// Always populate these all the way
|
||||||
populateType = BfPopulateType_Data;
|
if (populateType != BfPopulateType_IdentityNoRemapAlias)
|
||||||
|
populateType = BfPopulateType_Data;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resolvedTypeRef->IsSizedArray())
|
if (resolvedTypeRef->IsSizedArray())
|
||||||
|
@ -2730,7 +2764,7 @@ void BfModule::DoPopulateType_SetGenericDependencies(BfTypeInstance* genericType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::DoPopulateType_TypeAlias(BfTypeInstance* typeAlias)
|
void BfModule::DoPopulateType_TypeAlias(BfTypeAliasType* typeAlias)
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeAlias);
|
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeAlias);
|
||||||
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
|
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
|
||||||
|
@ -2766,6 +2800,8 @@ void BfModule::DoPopulateType_TypeAlias(BfTypeInstance* typeAlias)
|
||||||
aliasToType = ResolveTypeRef(typeAliasDecl->mAliasToType, BfPopulateType_IdentityNoRemapAlias);
|
aliasToType = ResolveTypeRef(typeAliasDecl->mAliasToType, BfPopulateType_IdentityNoRemapAlias);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BfLogSysM("DoPopulateType_TypeAlias %p %s = %p %s\n", typeAlias, TypeToString(typeAlias).c_str(), aliasToType, (aliasToType != NULL) ? TypeToString(aliasToType).c_str() : NULL);
|
||||||
|
|
||||||
if (aliasToType != NULL)
|
if (aliasToType != NULL)
|
||||||
{
|
{
|
||||||
if (aliasToType->IsConstExprValue())
|
if (aliasToType->IsConstExprValue())
|
||||||
|
@ -2776,16 +2812,19 @@ void BfModule::DoPopulateType_TypeAlias(BfTypeInstance* typeAlias)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aliasToType != NULL)
|
if (aliasToType != NULL)
|
||||||
{
|
{
|
||||||
AddDependency(aliasToType, typeAlias, BfDependencyMap::DependencyFlag_DerivedFrom);
|
AddDependency(aliasToType, typeAlias, BfDependencyMap::DependencyFlag_DerivedFrom);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mContext->mFailTypes.Add(typeAlias);
|
mContext->mFailTypes.Add(typeAlias);
|
||||||
|
|
||||||
if (typeAlias->mTypeFailed)
|
if (typeAlias->mTypeFailed)
|
||||||
aliasToType = NULL;
|
aliasToType = NULL;
|
||||||
|
|
||||||
((BfTypeAliasType*)typeAlias)->mAliasToType = aliasToType;
|
if ((typeAlias->mAliasToType != NULL) && (typeAlias->mAliasToType != aliasToType) && (!typeAlias->mDependencyMap.IsEmpty()))
|
||||||
|
mContext->RebuildDependentTypes_MidCompile(typeAlias, "type alias remapped");
|
||||||
|
|
||||||
|
typeAlias->mAliasToType = aliasToType;
|
||||||
|
|
||||||
if (aliasToType != NULL)
|
if (aliasToType != NULL)
|
||||||
{
|
{
|
||||||
|
@ -3188,9 +3227,10 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
if (resolvedTypeRef->IsTypeAlias())
|
if (resolvedTypeRef->IsTypeAlias())
|
||||||
{
|
{
|
||||||
prevTypeState.Restore();
|
prevTypeState.Restore();
|
||||||
DoPopulateType_TypeAlias(typeInstance);
|
DoPopulateType_TypeAlias((BfTypeAliasType*)typeInstance);
|
||||||
|
|
||||||
typeInstance->mTypeIncomplete = false;
|
typeInstance->mTypeIncomplete = false;
|
||||||
|
resolvedTypeRef->mRebuildFlags = BfTypeRebuildFlag_None;
|
||||||
resolvedTypeRef->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotted;
|
resolvedTypeRef->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotted;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4453,19 +4493,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
if (!typeInstance->mCeTypeInfo->mNext->mFailed)
|
if (!typeInstance->mCeTypeInfo->mNext->mFailed)
|
||||||
{
|
{
|
||||||
if ((typeInstance->mCeTypeInfo->mHash != typeInstance->mCeTypeInfo->mNext->mHash) && (!typeInstance->mCeTypeInfo->mHash.IsZero()))
|
if ((typeInstance->mCeTypeInfo->mHash != typeInstance->mCeTypeInfo->mNext->mHash) && (!typeInstance->mCeTypeInfo->mHash.IsZero()))
|
||||||
{
|
mContext->RebuildDependentTypes_MidCompile(typeInstance, "comptime hash changed");
|
||||||
int prevDeletedTypes = mCompiler->mStats.mTypesDeleted;
|
|
||||||
if (mCompiler->mIsResolveOnly)
|
|
||||||
mCompiler->mNeedsFullRefresh = true;
|
|
||||||
BfLogSysM("Type %p hash changed, rebuilding dependent types\n", typeInstance);
|
|
||||||
mContext->RebuildDependentTypes(typeInstance);
|
|
||||||
|
|
||||||
if (mCompiler->mStats.mTypesDeleted != prevDeletedTypes)
|
|
||||||
{
|
|
||||||
BfLogSysM("Type %p hash changed, rebuilding dependent types - updating after deleting types\n", typeInstance);
|
|
||||||
mContext->UpdateAfterDeletingTypes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
typeInstance->mCeTypeInfo->mOnCompileMap = typeInstance->mCeTypeInfo->mNext->mOnCompileMap;
|
typeInstance->mCeTypeInfo->mOnCompileMap = typeInstance->mCeTypeInfo->mNext->mOnCompileMap;
|
||||||
typeInstance->mCeTypeInfo->mTypeIFaceMap = typeInstance->mCeTypeInfo->mNext->mTypeIFaceMap;
|
typeInstance->mCeTypeInfo->mTypeIFaceMap = typeInstance->mCeTypeInfo->mNext->mTypeIFaceMap;
|
||||||
typeInstance->mCeTypeInfo->mHash = typeInstance->mCeTypeInfo->mNext->mHash;
|
typeInstance->mCeTypeInfo->mHash = typeInstance->mCeTypeInfo->mNext->mHash;
|
||||||
|
@ -8922,9 +8950,11 @@ BfType* BfModule::ResolveTypeResult(BfTypeReference* typeRef, BfType* resolvedTy
|
||||||
{
|
{
|
||||||
if (mCurTypeInstance != NULL)
|
if (mCurTypeInstance != NULL)
|
||||||
AddDependency(resolvedTypeRef, mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference);
|
AddDependency(resolvedTypeRef, mCurTypeInstance, BfDependencyMap::DependencyFlag_NameReference);
|
||||||
|
if (resolvedTypeRef->mDefineState == BfTypeDefineState_Undefined)
|
||||||
|
PopulateType(resolvedTypeRef);
|
||||||
if ((typeInstance->mCustomAttributes != NULL) && (!typeRef->IsTemporary()))
|
if ((typeInstance->mCustomAttributes != NULL) && (!typeRef->IsTemporary()))
|
||||||
CheckErrorAttributes(typeInstance, NULL, typeInstance->mCustomAttributes, typeRef);
|
CheckErrorAttributes(typeInstance, NULL, typeInstance->mCustomAttributes, typeRef);
|
||||||
resolvedTypeRef = resolvedTypeRef->GetUnderlyingType();
|
resolvedTypeRef = resolvedTypeRef->GetUnderlyingType();
|
||||||
if (resolvedTypeRef != NULL)
|
if (resolvedTypeRef != NULL)
|
||||||
typeInstance = resolvedTypeRef->ToTypeInstance();
|
typeInstance = resolvedTypeRef->ToTypeInstance();
|
||||||
else
|
else
|
||||||
|
@ -11088,7 +11118,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
if (BfResolvedTypeSet::Hash(refType, &lookupCtx) != resolvedEntry->mHash)
|
if (BfResolvedTypeSet::Hash(refType, &lookupCtx) != resolvedEntry->mHash)
|
||||||
{
|
{
|
||||||
int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx);
|
int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx, BfResolvedTypeSet::BfHashFlag_AllowRef);
|
||||||
int typeHash = BfResolvedTypeSet::Hash(refType, &lookupCtx);
|
int typeHash = BfResolvedTypeSet::Hash(refType, &lookupCtx);
|
||||||
BF_ASSERT(refHash == typeHash);
|
BF_ASSERT(refHash == typeHash);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "BfSource.h"
|
#include "BfSource.h"
|
||||||
#include "BfIRBuilder.h"
|
#include "BfIRBuilder.h"
|
||||||
#include "BeefySysLib/util/MultiHashSet.h"
|
#include "BeefySysLib/util/MultiHashSet.h"
|
||||||
|
#include "BeefySysLib/util/BitSet.h"
|
||||||
|
|
||||||
NS_BF_BEGIN
|
NS_BF_BEGIN
|
||||||
|
|
||||||
|
@ -428,7 +429,8 @@ enum BfTypeRebuildFlags
|
||||||
BfTypeRebuildFlag_ResolvingBase = 0x8000,
|
BfTypeRebuildFlag_ResolvingBase = 0x8000,
|
||||||
BfTypeRebuildFlag_InFailTypes = 0x10000,
|
BfTypeRebuildFlag_InFailTypes = 0x10000,
|
||||||
BfTypeRebuildFlag_RebuildQueued = 0x20000,
|
BfTypeRebuildFlag_RebuildQueued = 0x20000,
|
||||||
BfTypeRebuildFlag_ConstEvalCancelled = 0x40000
|
BfTypeRebuildFlag_ConstEvalCancelled = 0x40000,
|
||||||
|
BfTypeRebuildFlag_ChangedMidCompile = 0x80000,
|
||||||
};
|
};
|
||||||
|
|
||||||
class BfTypeDIReplaceCallback;
|
class BfTypeDIReplaceCallback;
|
||||||
|
@ -489,7 +491,7 @@ public:
|
||||||
|
|
||||||
BfContext* mContext;
|
BfContext* mContext;
|
||||||
int mTypeId;
|
int mTypeId;
|
||||||
int mRevision;
|
int mRevision;
|
||||||
|
|
||||||
// For Objects, align and size is ref-sized (object*).
|
// For Objects, align and size is ref-sized (object*).
|
||||||
// Use mInstSize/mInstAlign for actual data size/align
|
// Use mInstSize/mInstAlign for actual data size/align
|
||||||
|
@ -1842,6 +1844,12 @@ class BfGenericExtensionInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Dictionary<BfTypeDef*, BfGenericExtensionEntry> mExtensionMap;
|
Dictionary<BfTypeDef*, BfGenericExtensionEntry> mExtensionMap;
|
||||||
|
BitSet mConstraintsPassedSet;
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
mExtensionMap.Clear();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Note on nested generic types- mGenericParams is the accumulation of all generic params from outer to inner, so
|
// Note on nested generic types- mGenericParams is the accumulation of all generic params from outer to inner, so
|
||||||
|
|
|
@ -6122,7 +6122,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (varType == NULL)
|
if (varType == NULL)
|
||||||
varType = mContext->mBfObjectType;
|
varType = GetPrimitiveType(BfTypeCode_Var);
|
||||||
bool isArray = target.mType->IsArray();
|
bool isArray = target.mType->IsArray();
|
||||||
bool isSizedArray = target.mType->IsSizedArray();
|
bool isSizedArray = target.mType->IsSizedArray();
|
||||||
bool isVarEnumerator = target.mType->IsVar();
|
bool isVarEnumerator = target.mType->IsVar();
|
||||||
|
@ -6437,7 +6437,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nextEmbeddedType == NULL)
|
if (nextEmbeddedType == NULL)
|
||||||
nextEmbeddedType = mContext->mBfObjectType;
|
nextEmbeddedType = GetPrimitiveType(BfTypeCode_Var);
|
||||||
|
|
||||||
BfLocalVariable* itrLocalDef = NULL;
|
BfLocalVariable* itrLocalDef = NULL;
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace Tests
|
||||||
|
|
||||||
public struct Inner
|
public struct Inner
|
||||||
{
|
{
|
||||||
public const EnumA cVal = EnumA.C("InnerTest");
|
public const EnumA cVal = .C("InnerTest");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,14 @@ PUSHD %~dp0..\
|
||||||
@CALL :TEST
|
@CALL :TEST
|
||||||
@IF !ERRORLEVEL! NEQ 0 GOTO HADERROR
|
@IF !ERRORLEVEL! NEQ 0 GOTO HADERROR
|
||||||
|
|
||||||
|
@SET TESTPATH=IDE\Tests\BugW008
|
||||||
|
@CALL :TEST
|
||||||
|
@IF !ERRORLEVEL! NEQ 0 GOTO HADERROR
|
||||||
|
|
||||||
|
@SET TESTPATH=IDE\Tests\BugW009
|
||||||
|
@CALL :TEST
|
||||||
|
@IF !ERRORLEVEL! NEQ 0 GOTO HADERROR
|
||||||
|
|
||||||
@SET TESTPATH=IDE\Tests\IndentTest
|
@SET TESTPATH=IDE\Tests\IndentTest
|
||||||
@CALL :TEST
|
@CALL :TEST
|
||||||
@IF !ERRORLEVEL! NEQ 0 GOTO HADERROR
|
@IF !ERRORLEVEL! NEQ 0 GOTO HADERROR
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue