mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Optimizations, switching CanImplicitlyCast method, new CPU rate checker
This commit is contained in:
parent
39fd8d2624
commit
098ad1ce55
25 changed files with 759 additions and 301 deletions
|
@ -51,7 +51,7 @@ namespace System
|
||||||
{
|
{
|
||||||
if (mData & sIsEnumerating != 0)
|
if (mData & sIsEnumerating != 0)
|
||||||
{
|
{
|
||||||
Enumerator* enumerator = (Enumerator*)(mData & sDataMask);
|
Enumerator* enumerator = (Enumerator*)(void*)(mData & sDataMask);
|
||||||
return enumerator.[Friend]mTarget;
|
return enumerator.[Friend]mTarget;
|
||||||
}
|
}
|
||||||
return Internal.UnsafeCastToObject((void*)mData);
|
return Internal.UnsafeCastToObject((void*)mData);
|
||||||
|
@ -61,7 +61,7 @@ namespace System
|
||||||
{
|
{
|
||||||
if (mData & sIsEnumerating != 0)
|
if (mData & sIsEnumerating != 0)
|
||||||
{
|
{
|
||||||
Enumerator* enumerator = (Enumerator*)(mData & sDataMask);
|
Enumerator* enumerator = (Enumerator*)(void*)(mData & sDataMask);
|
||||||
enumerator.[Friend]mTarget = value;
|
enumerator.[Friend]mTarget = value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -249,12 +249,12 @@ namespace System
|
||||||
if (mEvent.mData & sIsEnumerating == 0)
|
if (mEvent.mData & sIsEnumerating == 0)
|
||||||
{
|
{
|
||||||
mTarget = mEvent.Target;
|
mTarget = mEvent.Target;
|
||||||
mEvent.mData = (int)(&this) | sIsEnumerating;
|
mEvent.mData = (int)(void*)(&this) | sIsEnumerating;
|
||||||
mRootEnumerator = &this;
|
mRootEnumerator = &this;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mRootEnumerator = (Enumerator*)(mEvent.mData & Event<T>.sDataMask);
|
mRootEnumerator = (Enumerator*)(void*)(mEvent.mData & Event<T>.sDataMask);
|
||||||
}
|
}
|
||||||
mIdx = -1;
|
mIdx = -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,7 +145,7 @@ namespace System.IO
|
||||||
if (sCurrentThis.mSelectedPath.Length != 0)
|
if (sCurrentThis.mSelectedPath.Length != 0)
|
||||||
{
|
{
|
||||||
// Try to select the folder specified by selectedPath
|
// Try to select the folder specified by selectedPath
|
||||||
Windows.SendMessageW(hWnd, Windows.BFFM_SETSELECTIONA, 1, (int)sCurrentThis.mSelectedPath.ToScopedNativeWChar!());
|
Windows.SendMessageW(hWnd, Windows.BFFM_SETSELECTIONA, 1, (int)(void*)sCurrentThis.mSelectedPath.ToScopedNativeWChar!());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Windows.BFFM_SELCHANGED:
|
case Windows.BFFM_SELCHANGED:
|
||||||
|
|
|
@ -438,7 +438,7 @@ namespace System.IO
|
||||||
{
|
{
|
||||||
using (sMonitor.Enter())
|
using (sMonitor.Enter())
|
||||||
{
|
{
|
||||||
var ofn = (Windows.OpenFileName*)lparam;
|
var ofn = (Windows.OpenFileName*)(void*)lparam;
|
||||||
sHookMap[(int)hWnd] = (CommonDialog)Internal.UnsafeCastToObject((void*)ofn.mCustData);
|
sHookMap[(int)hWnd] = (CommonDialog)Internal.UnsafeCastToObject((void*)ofn.mCustData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ namespace System
|
||||||
{
|
{
|
||||||
Type type;
|
Type type;
|
||||||
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||||
ClassVData* maskedVData = (ClassVData*)(mClassVData & ~(int)0xFF);
|
ClassVData* maskedVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
|
||||||
type = maskedVData.mType;
|
type = maskedVData.mType;
|
||||||
#else
|
#else
|
||||||
type = mClassVData.mType;
|
type = mClassVData.mType;
|
||||||
|
@ -63,7 +63,7 @@ namespace System
|
||||||
{
|
{
|
||||||
Type type;
|
Type type;
|
||||||
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||||
ClassVData* maskedVData = (ClassVData*)(mClassVData & ~(int)0xFF);
|
ClassVData* maskedVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
|
||||||
type = maskedVData.mType;
|
type = maskedVData.mType;
|
||||||
#else
|
#else
|
||||||
type = mClassVData.mType;
|
type = mClassVData.mType;
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace System
|
||||||
|
|
||||||
public int GetHashCode()
|
public int GetHashCode()
|
||||||
{
|
{
|
||||||
return (int)mVal;
|
return (int)(void*)mVal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1566,7 +1566,7 @@ namespace BeefPerf
|
||||||
uint32 tickMSNow = (.)ReadSLEB128();
|
uint32 tickMSNow = (.)ReadSLEB128();
|
||||||
int64 clockRate = (.)ReadSLEB128();
|
int64 clockRate = (.)ReadSLEB128();
|
||||||
|
|
||||||
mTicksToUSScale = 1000.0 / clockRate;
|
mTicksToUSScale = 1000000.0 / clockRate;
|
||||||
|
|
||||||
/*if (mFirstTimeStamp == -1)
|
/*if (mFirstTimeStamp == -1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -909,8 +909,25 @@ static void __cdecl AbortHandler(int)
|
||||||
BfpSystem_FatalError("Abort handler", NULL);
|
BfpSystem_FatalError("Abort handler", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int64 gCPUFreq = -1;
|
||||||
|
static int64 gStartCPUTick = -1;
|
||||||
|
static int64 gStartQPF = -1;
|
||||||
|
|
||||||
|
static void InitCPUFreq()
|
||||||
|
{
|
||||||
|
if (gStartCPUTick == -1)
|
||||||
|
{
|
||||||
|
gStartCPUTick = __rdtsc();
|
||||||
|
LARGE_INTEGER largeVal = { 0 };
|
||||||
|
QueryPerformanceCounter(&largeVal);
|
||||||
|
gStartQPF = largeVal.QuadPart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flags)
|
BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flags)
|
||||||
{
|
{
|
||||||
|
InitCPUFreq();
|
||||||
|
|
||||||
::_set_error_mode(_OUT_TO_STDERR);
|
::_set_error_mode(_OUT_TO_STDERR);
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
@ -1124,9 +1141,27 @@ BFP_EXPORT int64 BFP_CALLTYPE BfpSystem_GetCPUTick()
|
||||||
|
|
||||||
BFP_EXPORT int64 BFP_CALLTYPE BfpSystem_GetCPUTickFreq()
|
BFP_EXPORT int64 BFP_CALLTYPE BfpSystem_GetCPUTickFreq()
|
||||||
{
|
{
|
||||||
LARGE_INTEGER freq = { 0 };
|
LARGE_INTEGER largeVal = { 0 };
|
||||||
QueryPerformanceFrequency(&freq);
|
QueryPerformanceFrequency(&largeVal);
|
||||||
return freq.QuadPart;
|
int64 qpfFreq = largeVal.QuadPart;
|
||||||
|
|
||||||
|
if (gStartCPUTick == -1)
|
||||||
|
{
|
||||||
|
InitCPUFreq();
|
||||||
|
Sleep(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
int64 cpuTick1 = __rdtsc();
|
||||||
|
QueryPerformanceCounter(&largeVal);
|
||||||
|
int64 slowTick1 = largeVal.QuadPart;
|
||||||
|
|
||||||
|
int64 cpuElapsed = cpuTick1 - gStartCPUTick;
|
||||||
|
int64 slowElapsed = slowTick1 - gStartQPF;
|
||||||
|
double elapsedSeconds = slowElapsed / (double)qpfFreq;
|
||||||
|
int64 freq = (int64)(cpuElapsed / elapsedSeconds);
|
||||||
|
gCPUFreq = freq;
|
||||||
|
|
||||||
|
return gCPUFreq;
|
||||||
}
|
}
|
||||||
|
|
||||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_CreateGUID(BfpGUID* outGuid)
|
BFP_EXPORT void BFP_CALLTYPE BfpSystem_CreateGUID(BfpGUID* outGuid)
|
||||||
|
|
|
@ -639,7 +639,7 @@ public:
|
||||||
this->mSize++;
|
this->mSize++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Insert(intptr idx, T* vals, intptr size)
|
void Insert(intptr idx, const T* vals, intptr size)
|
||||||
{
|
{
|
||||||
BF_ASSERT((uintptr)idx <= (uintptr)this->mSize);
|
BF_ASSERT((uintptr)idx <= (uintptr)this->mSize);
|
||||||
if (this->mSize + size > this->mAllocSize)
|
if (this->mSize + size > this->mAllocSize)
|
||||||
|
@ -934,7 +934,7 @@ public:
|
||||||
this->mSize++;
|
this->mSize++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Insert(intptr idx, T* vals, intptr size)
|
void Insert(intptr idx, const T* vals, intptr size)
|
||||||
{
|
{
|
||||||
BF_ASSERT((uintptr)idx <= (uintptr)this->mSize);
|
BF_ASSERT((uintptr)idx <= (uintptr)this->mSize);
|
||||||
if (this->mSize + size > this->mAllocSize)
|
if (this->mSize + size > this->mAllocSize)
|
||||||
|
|
|
@ -355,7 +355,7 @@ static int64 GetTimestamp()
|
||||||
#ifdef BF_PLATFORM_WINDOWS
|
#ifdef BF_PLATFORM_WINDOWS
|
||||||
return __rdtsc() / 100;
|
return __rdtsc() / 100;
|
||||||
#else
|
#else
|
||||||
return BfpSystem_GetCPUTick();
|
return BfpSystem_GetCPUTick() / 100;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -186,7 +186,7 @@ public:
|
||||||
return mPrevSizes + (int)((uint8*)ptr - mCurAlloc);
|
return mPrevSizes + (int)((uint8*)ptr - mCurAlloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8* AllocBytes(int wantSize, int alignSize, const char* dbgName = "AllocBytes")
|
uint8* AllocBytes(intptr wantSize, int alignSize, const char* dbgName = "AllocBytes")
|
||||||
{
|
{
|
||||||
mCurPtr = (uint8*)(((intptr)mCurPtr + alignSize - 1) & ~(alignSize - 1));
|
mCurPtr = (uint8*)(((intptr)mCurPtr + alignSize - 1) & ~(alignSize - 1));
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@ public:
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8* AllocBytes(int wantSize, const char* dbgName = "AllocBytes")
|
uint8* AllocBytes(intptr wantSize, const char* dbgName = "AllocBytes")
|
||||||
{
|
{
|
||||||
#ifdef BUMPALLOC_TRACKALLOCS
|
#ifdef BUMPALLOC_TRACKALLOCS
|
||||||
BumpAllocTrackedEntry* allocSizePtr;
|
BumpAllocTrackedEntry* allocSizePtr;
|
||||||
|
@ -237,6 +237,11 @@ class AllocatorBump
|
||||||
public:
|
public:
|
||||||
BumpAllocator* mAlloc;
|
BumpAllocator* mAlloc;
|
||||||
|
|
||||||
|
AllocatorBump()
|
||||||
|
{
|
||||||
|
mAlloc = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
T* allocate(intptr count)
|
T* allocate(intptr count)
|
||||||
{
|
{
|
||||||
return (T*)mAlloc->AllocBytes((int)(sizeof(T) * count), alignof(T));
|
return (T*)mAlloc->AllocBytes((int)(sizeof(T) * count), alignof(T));
|
||||||
|
@ -245,6 +250,16 @@ public:
|
||||||
void deallocate(T* ptr)
|
void deallocate(T* ptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* rawAllocate(intptr size)
|
||||||
|
{
|
||||||
|
return mAlloc->AllocBytes(size, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rawDeallocate(void* ptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -107,6 +107,42 @@ void ChunkedDataBuffer::Write(uint8 byte)
|
||||||
mSize++;
|
mSize++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChunkedDataBuffer::Write_2(uint16 val)
|
||||||
|
{
|
||||||
|
while (mWriteCurPtr + 2 > mWriteCurAlloc + ALLOC_SIZE)
|
||||||
|
{
|
||||||
|
Write((uint8*)&val, 2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*(uint16*)mWriteCurPtr = val;
|
||||||
|
mWriteCurPtr += 2;
|
||||||
|
mSize += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChunkedDataBuffer::Write_3(uint32 val)
|
||||||
|
{
|
||||||
|
while (mWriteCurPtr + 3 > mWriteCurAlloc + ALLOC_SIZE)
|
||||||
|
{
|
||||||
|
Write((uint8*)&val, 3);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*(uint32*)mWriteCurPtr = val;
|
||||||
|
mWriteCurPtr += 3;
|
||||||
|
mSize += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChunkedDataBuffer::Write_4(uint32 val)
|
||||||
|
{
|
||||||
|
while (mWriteCurPtr + 4 > mWriteCurAlloc + ALLOC_SIZE)
|
||||||
|
{
|
||||||
|
Write((uint8*)&val, 4);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*(uint32*)mWriteCurPtr = val;
|
||||||
|
mWriteCurPtr += 4;
|
||||||
|
mSize += 4;
|
||||||
|
}
|
||||||
|
|
||||||
int ChunkedDataBuffer::GetReadPos()
|
int ChunkedDataBuffer::GetReadPos()
|
||||||
{
|
{
|
||||||
return mReadPoolIdx * ALLOC_SIZE + (int)(mReadCurPtr - mReadCurAlloc);
|
return mReadPoolIdx * ALLOC_SIZE + (int)(mReadCurPtr - mReadCurAlloc);
|
||||||
|
|
|
@ -32,6 +32,9 @@ public:
|
||||||
void GrowPool();
|
void GrowPool();
|
||||||
void Write(const void* data, int size);
|
void Write(const void* data, int size);
|
||||||
void Write(uint8 byte);
|
void Write(uint8 byte);
|
||||||
|
void Write_2(uint16 val);
|
||||||
|
void Write_3(uint32 val);
|
||||||
|
void Write_4(uint32 val);
|
||||||
int GetReadPos();
|
int GetReadPos();
|
||||||
void SetReadPos(int pos);
|
void SetReadPos(int pos);
|
||||||
void NextReadPool();
|
void NextReadPool();
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../Common.h"
|
#include "Array.h"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
NS_BF_BEGIN;
|
NS_BF_BEGIN;
|
||||||
|
|
||||||
template <typename TKey>
|
template <typename TKey, typename TAlloc = AllocatorCLib<TKey> >
|
||||||
class HashSet
|
class HashSet : public TAlloc
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef int int_cosize;
|
typedef int int_cosize;
|
||||||
|
@ -254,14 +254,14 @@ private:
|
||||||
Resize(ExpandSize(mCount), false);
|
Resize(ExpandSize(mCount), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resize(int newSize, bool forceNewHashCodes)
|
void Resize(intptr newSize, bool forceNewHashCodes)
|
||||||
{
|
{
|
||||||
BF_ASSERT(newSize >= mAllocSize);
|
BF_ASSERT(newSize >= mAllocSize);
|
||||||
int_cosize* newBuckets = new int_cosize[newSize];
|
int_cosize* newBuckets = (int_cosize*)rawAllocate(sizeof(int_cosize) * newSize);
|
||||||
for (int_cosize i = 0; i < newSize; i++)
|
for (int_cosize i = 0; i < newSize; i++)
|
||||||
newBuckets[i] = -1;
|
newBuckets[i] = -1;
|
||||||
Entry* newEntries = new Entry[newSize];
|
Entry* newEntries = (Entry*)rawAllocate(sizeof(Entry)*newSize);
|
||||||
//mEntries.CopyTo(newEntries, 0, 0, mCount);
|
|
||||||
for (int i = 0; i < mCount; i++)
|
for (int i = 0; i < mCount; i++)
|
||||||
{
|
{
|
||||||
auto& newEntry = newEntries[i];
|
auto& newEntry = newEntries[i];
|
||||||
|
@ -294,12 +294,12 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] mBuckets;
|
rawDeallocate(mBuckets);
|
||||||
delete[] mEntries;
|
rawDeallocate(mEntries);
|
||||||
|
|
||||||
mBuckets = newBuckets;
|
mBuckets = newBuckets;
|
||||||
mEntries = newEntries;
|
mEntries = newEntries;
|
||||||
mAllocSize = newSize;
|
mAllocSize = (int_cosize)newSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FindEntry(const TKey& key)
|
int FindEntry(const TKey& key)
|
||||||
|
@ -332,10 +332,10 @@ private:
|
||||||
void Initialize(intptr capacity)
|
void Initialize(intptr capacity)
|
||||||
{
|
{
|
||||||
int_cosize size = GetPrimeish((int_cosize)capacity);
|
int_cosize size = GetPrimeish((int_cosize)capacity);
|
||||||
mBuckets = new int_cosize[size];
|
mBuckets = (int_cosize*)rawAllocate(sizeof(int_cosize) * size);
|
||||||
mAllocSize = size;
|
mAllocSize = size;
|
||||||
for (int_cosize i = 0; i < (int_cosize)mAllocSize; i++) mBuckets[i] = -1;
|
for (int_cosize i = 0; i < (int_cosize)mAllocSize; i++) mBuckets[i] = -1;
|
||||||
mEntries = new Entry[size];
|
mEntries = (Entry*)rawAllocate(sizeof(Entry) * size);
|
||||||
mFreeList = -1;
|
mFreeList = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,8 +431,8 @@ public:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mBuckets = new int_cosize[mAllocSize];
|
mBuckets = (int_cosize*)rawAllocate(sizeof(int_cosize) * mAllocSize);
|
||||||
mEntries = new Entry[mAllocSize];
|
mEntries = (Entry*)rawAllocate(sizeof(Entry) * mAllocSize);
|
||||||
|
|
||||||
for (int_cosize i = 0; i < mAllocSize; i++)
|
for (int_cosize i = 0; i < mAllocSize; i++)
|
||||||
mBuckets[i] = val.mBuckets[i];
|
mBuckets[i] = val.mBuckets[i];
|
||||||
|
@ -476,8 +476,8 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] mBuckets;
|
rawDeallocate(mBuckets);
|
||||||
delete[] mEntries;
|
rawDeallocate(mEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
HashSet& operator=(const HashSet& rhs)
|
HashSet& operator=(const HashSet& rhs)
|
||||||
|
|
|
@ -288,6 +288,11 @@ public:
|
||||||
this->mSize = 0;
|
this->mSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
this->mSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*void Free()
|
/*void Free()
|
||||||
{
|
{
|
||||||
if (this->mVals != NULL)
|
if (this->mVals != NULL)
|
||||||
|
@ -1060,17 +1065,27 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static bool operator==(const ArrayBase<T>& arrA, const SizedArrayBase<T>& arrB)
|
||||||
|
{
|
||||||
|
if (arrA.mSize != arrB.mSize)
|
||||||
|
return false;
|
||||||
|
for (intptr i = 0; i < arrA.mSize; i++)
|
||||||
|
if (arrA.mVals[i] != arrB.mVals[i])
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
NS_BF_END;
|
NS_BF_END;
|
||||||
|
|
||||||
/*namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct hash<Beefy::Array<T> >
|
struct hash<Beefy::SizedArrayImpl<T> >
|
||||||
{
|
{
|
||||||
size_t operator()(const Beefy::Array<T>& val) const
|
size_t operator()(const Beefy::SizedArrayImpl<T>& val) const
|
||||||
{
|
{
|
||||||
return _Hash_seq((const uint8*)val.mVals, sizeof(T) * val.mSize);
|
return HashBytes((const uint8*)val.mVals, sizeof(T) * val.mSize);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}*/
|
}
|
||||||
|
|
||||||
|
|
|
@ -993,6 +993,8 @@ bool BfMethodMatcher::WantsCheckMethod(BfProtectionCheckFlags& flags, BfTypeInst
|
||||||
|
|
||||||
bool BfMethodMatcher::CheckMethod(BfTypeInstance* typeInstance, BfMethodDef* checkMethod, bool isFailurePass)
|
bool BfMethodMatcher::CheckMethod(BfTypeInstance* typeInstance, BfMethodDef* checkMethod, bool isFailurePass)
|
||||||
{
|
{
|
||||||
|
BP_ZONE("BfMethodMatcher::CheckMethod");
|
||||||
|
|
||||||
bool hadMatch = false;
|
bool hadMatch = false;
|
||||||
|
|
||||||
// Never consider overrides - they only get found at original method declaration
|
// Never consider overrides - they only get found at original method declaration
|
||||||
|
@ -2905,7 +2907,9 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfIdentifierNode* identifierNode,
|
||||||
return qualifiedResult;
|
return qualifiedResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
return LookupIdentifier(identifierNode, identifierNode->ToString(), ignoreInitialError, hadError);
|
StringT<128> identifierStr;
|
||||||
|
identifierNode->ToString(identifierStr);
|
||||||
|
return LookupIdentifier(identifierNode, identifierStr, ignoreInitialError, hadError);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfExprEvaluator::Visit(BfIdentifierNode* identifierNode)
|
void BfExprEvaluator::Visit(BfIdentifierNode* identifierNode)
|
||||||
|
@ -3148,7 +3152,7 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
|
||||||
|
|
||||||
if (resolvedFieldType->IsValuelessType())
|
if (resolvedFieldType->IsValuelessType())
|
||||||
{
|
{
|
||||||
return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), resolvedFieldType, true);
|
return BfTypedValue(BfIRValue::sValueless, resolvedFieldType, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isConst)
|
if (isConst)
|
||||||
|
@ -7286,7 +7290,6 @@ void BfExprEvaluator::LookupQualifiedStaticField(BfQualifiedNameNode* nameNode,
|
||||||
{
|
{
|
||||||
// Lookup left side as a type
|
// Lookup left side as a type
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<bool> prevHadIgnoreError(mModule->mHadIgnoredError, false);
|
|
||||||
BfType* type = NULL;
|
BfType* type = NULL;
|
||||||
{
|
{
|
||||||
type = mModule->ResolveTypeRef(nameNode->mLeft, NULL, BfPopulateType_Data, BfResolveTypeRefFlag_AllowRef);
|
type = mModule->ResolveTypeRef(nameNode->mLeft, NULL, BfPopulateType_Data, BfResolveTypeRefFlag_AllowRef);
|
||||||
|
@ -7372,7 +7375,6 @@ void BfExprEvaluator::LookupQualifiedStaticField(BfAstNode* nameNode, BfIdentifi
|
||||||
{
|
{
|
||||||
// Lookup left side as a type
|
// Lookup left side as a type
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<bool> prevHadIgnoreError(mModule->mHadIgnoredError, false);
|
|
||||||
BfType* type = NULL;
|
BfType* type = NULL;
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
|
SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
|
||||||
|
@ -8349,6 +8351,7 @@ bool BfExprEvaluator::CanBindDelegate(BfDelegateBindExpression* delegateBindExpr
|
||||||
for (int i = 0; i < (int) methodInstance->GetParamCount(); i++)
|
for (int i = 0; i < (int) methodInstance->GetParamCount(); i++)
|
||||||
{
|
{
|
||||||
auto typedValueExpr = &typedValueExprs[i];
|
auto typedValueExpr = &typedValueExprs[i];
|
||||||
|
typedValueExpr->mTypedValue.mValue = BfIRValue(BfIRValueFlags_Value, -1);
|
||||||
typedValueExpr->mTypedValue.mType = methodInstance->GetParamType(i);
|
typedValueExpr->mTypedValue.mType = methodInstance->GetParamType(i);
|
||||||
typedValueExpr->mRefNode = NULL;
|
typedValueExpr->mRefNode = NULL;
|
||||||
args[i] = typedValueExpr;
|
args[i] = typedValueExpr;
|
||||||
|
@ -8734,6 +8737,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
||||||
for (int i = 0; i < (int)methodInstance->GetParamCount(); i++)
|
for (int i = 0; i < (int)methodInstance->GetParamCount(); i++)
|
||||||
{
|
{
|
||||||
auto typedValueExpr = &typedValueExprs[i];
|
auto typedValueExpr = &typedValueExprs[i];
|
||||||
|
typedValueExpr->mTypedValue.mValue = BfIRValue(BfIRValueFlags_Value, -1);
|
||||||
typedValueExpr->mTypedValue.mType = methodInstance->GetParamType(i);
|
typedValueExpr->mTypedValue.mType = methodInstance->GetParamType(i);
|
||||||
typedValueExpr->mRefNode = NULL;
|
typedValueExpr->mRefNode = NULL;
|
||||||
args[i] = typedValueExpr;
|
args[i] = typedValueExpr;
|
||||||
|
@ -13160,13 +13164,13 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
||||||
if (mayBeSkipCall)
|
if (mayBeSkipCall)
|
||||||
resolveArgsFlags = (BfResolveArgFlags)(resolveArgsFlags | BfResolveArgFlag_DeferParamValues);
|
resolveArgsFlags = (BfResolveArgFlags)(resolveArgsFlags | BfResolveArgFlag_DeferParamValues);
|
||||||
|
|
||||||
// static int sCallIdx = 0;
|
static int sCallIdx = 0;
|
||||||
// sCallIdx++;
|
sCallIdx++;
|
||||||
// int callIdx = sCallIdx;
|
int callIdx = sCallIdx;
|
||||||
// if (callIdx == 1557)
|
if (callIdx == 1557)
|
||||||
// {
|
{
|
||||||
// NOP;
|
NOP;
|
||||||
// }
|
}
|
||||||
|
|
||||||
BfCheckedKind checkedKind = BfCheckedKind_NotSet;
|
BfCheckedKind checkedKind = BfCheckedKind_NotSet;
|
||||||
if (attributeState.mCustomAttributes != NULL)
|
if (attributeState.mCustomAttributes != NULL)
|
||||||
|
@ -17208,8 +17212,8 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
||||||
|
|
||||||
BfPointerType* resultPointerType = (BfPointerType*)resultType;
|
BfPointerType* resultPointerType = (BfPointerType*)resultType;
|
||||||
BfType* intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
BfType* intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
||||||
convLeftValue = mModule->CastToValue(leftExpression, leftValue, intPtrType, BfCastFlags_Explicit);
|
convLeftValue = mModule->CastToValue(leftExpression, leftValue, intPtrType, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromCompiler));
|
||||||
convRightValue = mModule->CastToValue(rightExpression, rightValue, intPtrType, BfCastFlags_Explicit);
|
convRightValue = mModule->CastToValue(rightExpression, rightValue, intPtrType, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromCompiler));
|
||||||
BfIRValue diffValue = mModule->mBfIRBuilder->CreateSub(convLeftValue, convRightValue);
|
BfIRValue diffValue = mModule->mBfIRBuilder->CreateSub(convLeftValue, convRightValue);
|
||||||
diffValue = mModule->mBfIRBuilder->CreateDiv(diffValue, mModule->GetConstValue(resultPointerType->mElementType->mSize, intPtrType), true);
|
diffValue = mModule->mBfIRBuilder->CreateDiv(diffValue, mModule->GetConstValue(resultPointerType->mElementType->mSize, intPtrType), true);
|
||||||
mResult = BfTypedValue(diffValue, intPtrType);
|
mResult = BfTypedValue(diffValue, intPtrType);
|
||||||
|
|
|
@ -215,6 +215,8 @@ static llvm::GlobalValue::LinkageTypes LLVMMapLinkageType(BfIRLinkageType linkag
|
||||||
return llvmLinkageType;
|
return llvmLinkageType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BfIRValue BfIRValue::sValueless(BfIRValueFlags_Value, -1);
|
||||||
|
|
||||||
bool BfIRValue::IsFake() const
|
bool BfIRValue::IsFake() const
|
||||||
{
|
{
|
||||||
return mId < -1;
|
return mId < -1;
|
||||||
|
@ -1452,6 +1454,98 @@ void BfIRBuilder::WriteSLEB128(int64 value)
|
||||||
while (hasMore);
|
while (hasMore);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BfIRBuilder::WriteSLEB128(int32 value)
|
||||||
|
{
|
||||||
|
if (value < 0)
|
||||||
|
{
|
||||||
|
// if (value >= -0x40)
|
||||||
|
// {
|
||||||
|
// mStream.Write((uint8)value);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (value >= -0x2000)
|
||||||
|
// {
|
||||||
|
// uint16 val =
|
||||||
|
// (((uint16)(value << 1)) & 0x7F00) |
|
||||||
|
// (((uint16)value) & 0x7F) | 0x80;
|
||||||
|
// mStream.Write_2(val);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (value >= -0x100000)
|
||||||
|
// {
|
||||||
|
// uint32 val =
|
||||||
|
// (((uint32)(value << 2)) & 0x7F0000) |
|
||||||
|
// (((uint32)(value << 1)) & 0x7F00) |
|
||||||
|
// (((uint32)value) & 0x7F) | 0x8080;
|
||||||
|
// mStream.Write_3(val);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (value >= -0x8000000)
|
||||||
|
// {
|
||||||
|
// uint32 val =
|
||||||
|
// (((uint32)(value << 3)) & 0x7F000000) |
|
||||||
|
// (((uint32)(value << 2)) & 0x7F0000) |
|
||||||
|
// (((uint32)(value << 1)) & 0x7F00) |
|
||||||
|
// (((uint32)value) & 0x7F) | 0x808080;
|
||||||
|
// mStream.Write_4(val);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (value <= 0x3F)
|
||||||
|
{
|
||||||
|
mStream.Write((uint8)value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value <= 0x1FFF)
|
||||||
|
{
|
||||||
|
uint16 val =
|
||||||
|
(((uint16)(value << 1)) & 0x7F00) |
|
||||||
|
(((uint16)value) & 0x7F) | 0x80;
|
||||||
|
mStream.Write_2(val);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// if (value <= 0x0FFFFF)
|
||||||
|
// {
|
||||||
|
// uint32 val =
|
||||||
|
// (((uint32)(value << 2)) & 0x7F0000) |
|
||||||
|
// (((uint32)(value << 1)) & 0x7F00) |
|
||||||
|
// (((uint32)value) & 0x7F) | 0x8080;
|
||||||
|
// mStream.Write_3(val);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (value <= 0x7FFFFF)
|
||||||
|
// {
|
||||||
|
// uint32 val =
|
||||||
|
// (((uint32)(value << 3)) & 0x7F000000) |
|
||||||
|
// (((uint32)(value << 2)) & 0x7F0000) |
|
||||||
|
// (((uint32)(value << 1)) & 0x7F00) |
|
||||||
|
// (((uint32)value) & 0x7F) | 0x808080;
|
||||||
|
// mStream.Write_4(val);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasMore;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
uint8 curByte = (uint8)(value & 0x7f);
|
||||||
|
value >>= 7;
|
||||||
|
hasMore = !((((value == 0) && ((curByte & 0x40) == 0)) ||
|
||||||
|
((value == -1) && ((curByte & 0x40) != 0))));
|
||||||
|
if (hasMore)
|
||||||
|
curByte |= 0x80;
|
||||||
|
mStream.Write(curByte);
|
||||||
|
} while (hasMore);
|
||||||
|
}
|
||||||
|
|
||||||
void BfIRBuilder::Write(uint8 val)
|
void BfIRBuilder::Write(uint8 val)
|
||||||
{
|
{
|
||||||
mStream.Write(val);
|
mStream.Write(val);
|
||||||
|
@ -4550,21 +4644,21 @@ BfIRMDNode BfIRBuilder::DbgCreateImportedModule(BfIRMDNode context, BfIRMDNode n
|
||||||
|
|
||||||
BfIRMDNode BfIRBuilder::DbgCreateBasicType(const StringImpl& name, int64 sizeInBits, int64 alignInBits, int encoding)
|
BfIRMDNode BfIRBuilder::DbgCreateBasicType(const StringImpl& name, int64 sizeInBits, int64 alignInBits, int encoding)
|
||||||
{
|
{
|
||||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateBasicType, name, sizeInBits, alignInBits, encoding);
|
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateBasicType, name, (int32)sizeInBits, (int32)alignInBits, encoding);
|
||||||
NEW_CMD_INSERTED_IRMD;
|
NEW_CMD_INSERTED_IRMD;
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfIRMDNode BfIRBuilder::DbgCreateStructType(BfIRMDNode context, const StringImpl& name, BfIRMDNode file, int lineNum, int64 sizeInBits, int64 alignInBits, int flags, BfIRMDNode derivedFrom, const BfSizedArray<BfIRMDNode>& elements)
|
BfIRMDNode BfIRBuilder::DbgCreateStructType(BfIRMDNode context, const StringImpl& name, BfIRMDNode file, int lineNum, int64 sizeInBits, int64 alignInBits, int flags, BfIRMDNode derivedFrom, const BfSizedArray<BfIRMDNode>& elements)
|
||||||
{
|
{
|
||||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateStructType, context, name, file, lineNum, sizeInBits, alignInBits, flags, derivedFrom, elements);
|
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateStructType, context, name, file, lineNum, (int32)sizeInBits, (int32)alignInBits, flags, derivedFrom, elements);
|
||||||
NEW_CMD_INSERTED_IRMD;
|
NEW_CMD_INSERTED_IRMD;
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfIRMDNode BfIRBuilder::DbgCreateEnumerationType(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNumber, int64 sizeInBits, int64 alignInBits, const BfSizedArray<BfIRMDNode>& elements, BfIRMDNode underlyingType)
|
BfIRMDNode BfIRBuilder::DbgCreateEnumerationType(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNumber, int64 sizeInBits, int64 alignInBits, const BfSizedArray<BfIRMDNode>& elements, BfIRMDNode underlyingType)
|
||||||
{
|
{
|
||||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateEnumerationType, scope, name, file, lineNumber, sizeInBits, alignInBits, elements, underlyingType);
|
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateEnumerationType, scope, name, file, lineNumber, (int32)sizeInBits, (int32)alignInBits, elements, underlyingType);
|
||||||
NEW_CMD_INSERTED_IRMD;
|
NEW_CMD_INSERTED_IRMD;
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
@ -4606,7 +4700,7 @@ BfIRMDNode BfIRBuilder::DbgCreateArrayType(int64 sizeInBits, int64 alignInBits,
|
||||||
|
|
||||||
BfIRMDNode BfIRBuilder::DbgCreateReplaceableCompositeType(int tag, const StringImpl& name, BfIRMDNode scope, BfIRMDNode file, int line, int64 sizeInBits, int64 alignInBits, int flags)
|
BfIRMDNode BfIRBuilder::DbgCreateReplaceableCompositeType(int tag, const StringImpl& name, BfIRMDNode scope, BfIRMDNode file, int line, int64 sizeInBits, int64 alignInBits, int flags)
|
||||||
{
|
{
|
||||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateReplaceableCompositeType, tag, name, scope, file, line, sizeInBits, alignInBits, flags);
|
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateReplaceableCompositeType, tag, name, scope, file, line, (int32)sizeInBits, (int32)alignInBits, flags);
|
||||||
NEW_CMD_INSERTED_IRMD;
|
NEW_CMD_INSERTED_IRMD;
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
@ -4627,7 +4721,7 @@ BfIRMDNode BfIRBuilder::DbgCreateForwardDecl(int tag, const StringImpl& name, Bf
|
||||||
|
|
||||||
BfIRMDNode BfIRBuilder::DbgCreateSizedForwardDecl(int tag, const StringImpl& name, BfIRMDNode scope, BfIRMDNode file, int line, int64 sizeInBits, int64 alignInBits)
|
BfIRMDNode BfIRBuilder::DbgCreateSizedForwardDecl(int tag, const StringImpl& name, BfIRMDNode scope, BfIRMDNode file, int line, int64 sizeInBits, int64 alignInBits)
|
||||||
{
|
{
|
||||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateSizedForwardDecl, tag, name, scope, file, line, sizeInBits, alignInBits);
|
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateSizedForwardDecl, tag, name, scope, file, line, (int32)sizeInBits, (int32)alignInBits);
|
||||||
NEW_CMD_INSERTED_IRMD;
|
NEW_CMD_INSERTED_IRMD;
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
@ -4661,7 +4755,7 @@ BfIRMDNode BfIRBuilder::DbgCreateEnumerator(const StringImpl& name, int64 val)
|
||||||
|
|
||||||
BfIRMDNode BfIRBuilder::DbgCreateMemberType(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNumber, int64 sizeInBits, int64 alignInBits, int64 offsetInBits, int flags, BfIRMDNode type)
|
BfIRMDNode BfIRBuilder::DbgCreateMemberType(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNumber, int64 sizeInBits, int64 alignInBits, int64 offsetInBits, int flags, BfIRMDNode type)
|
||||||
{
|
{
|
||||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateMemberType, scope, name, file, lineNumber, sizeInBits, alignInBits, offsetInBits, flags, type);
|
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateMemberType, scope, name, file, lineNumber, (int32)sizeInBits, (int32)alignInBits, (int32)offsetInBits, flags, type);
|
||||||
NEW_CMD_INSERTED_IRMD;
|
NEW_CMD_INSERTED_IRMD;
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
@ -4675,7 +4769,7 @@ BfIRMDNode BfIRBuilder::DbgCreateStaticMemberType(BfIRMDNode scope, const String
|
||||||
|
|
||||||
BfIRMDNode BfIRBuilder::DbgCreateInheritance(BfIRMDNode type, BfIRMDNode baseType, int64 baseOffset, int flags)
|
BfIRMDNode BfIRBuilder::DbgCreateInheritance(BfIRMDNode type, BfIRMDNode baseType, int64 baseOffset, int flags)
|
||||||
{
|
{
|
||||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateInheritance, type, baseType, baseOffset, flags);
|
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateInheritance, type, baseType, (int32)baseOffset, flags);
|
||||||
NEW_CMD_INSERTED_IRMD;
|
NEW_CMD_INSERTED_IRMD;
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
|
@ -473,6 +473,7 @@ public:
|
||||||
public:
|
public:
|
||||||
int mId;
|
int mId;
|
||||||
BfIRValueFlags mFlags;
|
BfIRValueFlags mFlags;
|
||||||
|
static BfIRValue sValueless;
|
||||||
|
|
||||||
#ifdef CHECK_CONSTHOLDER
|
#ifdef CHECK_CONSTHOLDER
|
||||||
BfIRConstHolder* mHolder;
|
BfIRConstHolder* mHolder;
|
||||||
|
@ -884,6 +885,7 @@ public:
|
||||||
~BfIRBuilder();
|
~BfIRBuilder();
|
||||||
|
|
||||||
void WriteSLEB128(int64 val);
|
void WriteSLEB128(int64 val);
|
||||||
|
void WriteSLEB128(int32 val);
|
||||||
void Write(uint8 val);
|
void Write(uint8 val);
|
||||||
void Write(bool val);
|
void Write(bool val);
|
||||||
void Write(int val);
|
void Write(int val);
|
||||||
|
|
|
@ -304,7 +304,7 @@ void BfGNUMangler::MangleTypeInst(MangleContext& mangleContext, StringImpl& name
|
||||||
name += "N8delegateI";
|
name += "N8delegateI";
|
||||||
else
|
else
|
||||||
name += "N8functionI";
|
name += "N8functionI";
|
||||||
BfTypeVector typeVec;
|
SizedArray<BfType*, 8> typeVec;
|
||||||
typeVec.push_back(invokeMethodInst->mReturnType);
|
typeVec.push_back(invokeMethodInst->mReturnType);
|
||||||
for (int paramIdx = 0; paramIdx < (int)invokeMethodInst->mParams.size(); paramIdx++)
|
for (int paramIdx = 0; paramIdx < (int)invokeMethodInst->mParams.size(); paramIdx++)
|
||||||
{
|
{
|
||||||
|
@ -1095,7 +1095,7 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl&
|
||||||
{
|
{
|
||||||
auto tupleType = (BfTupleType*)newNameSub.mType;
|
auto tupleType = (BfTupleType*)newNameSub.mType;
|
||||||
name += "?$__TUPLE";
|
name += "?$__TUPLE";
|
||||||
BfTypeVector typeVec;
|
SizedArray<BfType*, 8> typeVec;
|
||||||
for (auto& fieldInst : tupleType->mFieldInstances)
|
for (auto& fieldInst : tupleType->mFieldInstances)
|
||||||
{
|
{
|
||||||
BfFieldDef* fieldDef = fieldInst.GetFieldDef();
|
BfFieldDef* fieldDef = fieldInst.GetFieldDef();
|
||||||
|
@ -1120,7 +1120,7 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl&
|
||||||
name += "?$delegate";
|
name += "?$delegate";
|
||||||
else
|
else
|
||||||
name += "?$function";
|
name += "?$function";
|
||||||
BfTypeVector typeVec;
|
SizedArray<BfType*, 8> typeVec;
|
||||||
typeVec.push_back(BfNodeDynCast<BfDirectTypeReference>(methodDef->mReturnTypeRef)->mType);
|
typeVec.push_back(BfNodeDynCast<BfDirectTypeReference>(methodDef->mReturnTypeRef)->mType);
|
||||||
for (int paramIdx = 0; paramIdx < (int)methodDef->mParams.size(); paramIdx++)
|
for (int paramIdx = 0; paramIdx < (int)methodDef->mParams.size(); paramIdx++)
|
||||||
{
|
{
|
||||||
|
@ -1139,7 +1139,7 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl&
|
||||||
// name += "?$delegate";
|
// name += "?$delegate";
|
||||||
// else
|
// else
|
||||||
// name += "?$function";
|
// name += "?$function";
|
||||||
// BfTypeVector typeVec;
|
// SizedArray<BfType*, 8> typeVec;
|
||||||
// typeVec.push_back(invokeMethodInst->mReturnType);
|
// typeVec.push_back(invokeMethodInst->mReturnType);
|
||||||
// for (int paramIdx = 0; paramIdx < (int)invokeMethodInst->mParams.size(); paramIdx++)
|
// for (int paramIdx = 0; paramIdx < (int)invokeMethodInst->mParams.size(); paramIdx++)
|
||||||
// {
|
// {
|
||||||
|
@ -1156,7 +1156,7 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl&
|
||||||
{
|
{
|
||||||
auto boxedType = (BfBoxedType*)newNameSub.mTypeInst;
|
auto boxedType = (BfBoxedType*)newNameSub.mTypeInst;
|
||||||
name += "?$Box@";
|
name += "?$Box@";
|
||||||
BfTypeVector typeVec;
|
SizedArray<BfType*, 8> typeVec;
|
||||||
typeVec.push_back(boxedType->GetModifiedElementType());
|
typeVec.push_back(boxedType->GetModifiedElementType());
|
||||||
AddGenericArgs(mangleContext, name, typeVec);
|
AddGenericArgs(mangleContext, name, typeVec);
|
||||||
name += '@';
|
name += '@';
|
||||||
|
|
|
@ -804,7 +804,6 @@ BfModule::BfModule(BfContext* context, const StringImpl& moduleName)
|
||||||
mHadBuildWarning = false;
|
mHadBuildWarning = false;
|
||||||
mIgnoreErrors = false;
|
mIgnoreErrors = false;
|
||||||
mIgnoreWarnings = false;
|
mIgnoreWarnings = false;
|
||||||
mHadIgnoredError = false;
|
|
||||||
mReportErrors = true;
|
mReportErrors = true;
|
||||||
mIsInsideAutoComplete = false;
|
mIsInsideAutoComplete = false;
|
||||||
mIsDeleting = false;
|
mIsDeleting = false;
|
||||||
|
@ -1374,7 +1373,7 @@ BfTypedValue BfModule::GetFakeTypedValue(BfType* type)
|
||||||
{
|
{
|
||||||
// This is a conservative "IsValueless", since it's not an error to use a fakeVal even if we don't need one
|
// This is a conservative "IsValueless", since it's not an error to use a fakeVal even if we don't need one
|
||||||
if (type->mSize == 0)
|
if (type->mSize == 0)
|
||||||
return BfTypedValue(BfIRValue(), type);
|
return BfTypedValue(BfIRValue::sValueless, type);
|
||||||
else
|
else
|
||||||
return BfTypedValue(mBfIRBuilder->GetFakeVal(), type);
|
return BfTypedValue(mBfIRBuilder->GetFakeVal(), type);
|
||||||
}
|
}
|
||||||
|
@ -2447,7 +2446,6 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers
|
||||||
|
|
||||||
if (mIgnoreErrors)
|
if (mIgnoreErrors)
|
||||||
{
|
{
|
||||||
mHadIgnoredError = true;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8320,6 +8318,9 @@ void BfModule::EmitDynamicCastCheck(const BfTypedValue& targetValue, BfType* tar
|
||||||
|
|
||||||
void BfModule::EmitDynamicCastCheck(BfTypedValue typedVal, BfType* type, bool allowNull)
|
void BfModule::EmitDynamicCastCheck(BfTypedValue typedVal, BfType* type, bool allowNull)
|
||||||
{
|
{
|
||||||
|
if (mBfIRBuilder->mIgnoreWrites)
|
||||||
|
return;
|
||||||
|
|
||||||
bool emitDynamicCastCheck = mCompiler->mOptions.mEmitDynamicCastCheck;
|
bool emitDynamicCastCheck = mCompiler->mOptions.mEmitDynamicCastCheck;
|
||||||
auto typeOptions = GetTypeOptions();
|
auto typeOptions = GetTypeOptions();
|
||||||
if (typeOptions != NULL)
|
if (typeOptions != NULL)
|
||||||
|
@ -8355,6 +8356,12 @@ void BfModule::EmitDynamicCastCheck(BfTypedValue typedVal, BfType* type, bool al
|
||||||
|
|
||||||
BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfType* toType, const BfAllocTarget& allocTarget, bool callDtor)
|
BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfType* toType, const BfAllocTarget& allocTarget, bool callDtor)
|
||||||
{
|
{
|
||||||
|
if (mBfIRBuilder->mIgnoreWrites)
|
||||||
|
{
|
||||||
|
if (toType == mContext->mBfObjectType)
|
||||||
|
return BfTypedValue(mBfIRBuilder->GetFakeVal(), toType);
|
||||||
|
}
|
||||||
|
|
||||||
BP_ZONE("BoxValue");
|
BP_ZONE("BoxValue");
|
||||||
|
|
||||||
BfTypeInstance* fromStructTypeInstance = typedVal.mType->ToTypeInstance();
|
BfTypeInstance* fromStructTypeInstance = typedVal.mType->ToTypeInstance();
|
||||||
|
@ -8365,10 +8372,19 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
auto innerType = typedVal.mType->GetUnderlyingType();
|
auto innerType = typedVal.mType->GetUnderlyingType();
|
||||||
if (!innerType->IsValueType())
|
if (!innerType->IsValueType())
|
||||||
{
|
{
|
||||||
Fail("Only value types can be boxed", srcNode);
|
if (!mIgnoreErrors)
|
||||||
|
Fail("Only value types can be boxed", srcNode);
|
||||||
return BfTypedValue();
|
return BfTypedValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto boxedType = CreateBoxedType(innerType);
|
||||||
|
auto resultType = toType;
|
||||||
|
if (resultType == NULL)
|
||||||
|
resultType = boxedType;
|
||||||
|
|
||||||
|
if (mBfIRBuilder->mIgnoreWrites)
|
||||||
|
return BfTypedValue(mBfIRBuilder->GetFakeVal(), resultType);
|
||||||
|
|
||||||
auto prevBB = mBfIRBuilder->GetInsertBlock();
|
auto prevBB = mBfIRBuilder->GetInsertBlock();
|
||||||
auto boxBB = mBfIRBuilder->CreateBlock("boxedN.notNull");
|
auto boxBB = mBfIRBuilder->CreateBlock("boxedN.notNull");
|
||||||
auto endBB = mBfIRBuilder->CreateBlock("boxedN.end");
|
auto endBB = mBfIRBuilder->CreateBlock("boxedN.end");
|
||||||
|
@ -8379,11 +8395,7 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
|
|
||||||
mBfIRBuilder->CreateCondBr(hasValue, boxBB, endBB);
|
mBfIRBuilder->CreateCondBr(hasValue, boxBB, endBB);
|
||||||
|
|
||||||
auto boxedType = CreateBoxedType(innerType);
|
|
||||||
AddDependency(boxedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields);
|
AddDependency(boxedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields);
|
||||||
auto resultType = toType;
|
|
||||||
if (resultType == NULL)
|
|
||||||
resultType = boxedType;
|
|
||||||
|
|
||||||
mBfIRBuilder->AddBlock(boxBB);
|
mBfIRBuilder->AddBlock(boxBB);
|
||||||
mBfIRBuilder->SetInsertPoint(boxBB);
|
mBfIRBuilder->SetInsertPoint(boxBB);
|
||||||
|
@ -8444,15 +8456,14 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
return BfTypedValue();
|
return BfTypedValue();
|
||||||
|
|
||||||
// Need to box it
|
// Need to box it
|
||||||
auto boxedType = CreateBoxedType(typedVal.mType);
|
bool isBoxedType = (fromStructTypeInstance != NULL) && (toType->IsBoxed());
|
||||||
bool isBoxedType = (fromStructTypeInstance != NULL) && (toType->IsBoxed()) && (boxedType == toType);
|
|
||||||
|
|
||||||
if ((toType == NULL) || (toType == mContext->mBfObjectType) || (isBoxedType) || (alreadyCheckedCast) || (TypeIsSubTypeOf(fromStructTypeInstance, toTypeInstance)))
|
if ((toType == NULL) || (toType == mContext->mBfObjectType) || (isBoxedType) || (alreadyCheckedCast) || (TypeIsSubTypeOf(fromStructTypeInstance, toTypeInstance)))
|
||||||
{
|
{
|
||||||
if (typedVal.mType->IsPointer())
|
if (mBfIRBuilder->mIgnoreWrites)
|
||||||
{
|
return BfTypedValue(mBfIRBuilder->GetFakeVal(), (toType != NULL) ? toType : CreateBoxedType(typedVal.mType));
|
||||||
NOP;
|
|
||||||
}
|
auto boxedType = CreateBoxedType(typedVal.mType);
|
||||||
|
|
||||||
mBfIRBuilder->PopulateType(boxedType);
|
mBfIRBuilder->PopulateType(boxedType);
|
||||||
AddDependency(boxedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields);
|
AddDependency(boxedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields);
|
||||||
|
@ -8463,7 +8474,7 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
|
|
||||||
if (boxedType->IsUnspecializedType())
|
if (boxedType->IsUnspecializedType())
|
||||||
{
|
{
|
||||||
BF_ASSERT(mCurMethodInstance->mIsUnspecialized);
|
BF_ASSERT((srcNode == NULL) || (mCurMethodInstance->mIsUnspecialized));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -8656,7 +8667,7 @@ int BfModule::GetGenericParamAndReturnCount(BfMethodInstance* methodInstance)
|
||||||
return genericCount;
|
return genericCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfModule* BfModule::GetSpecializedMethodModule(const Array<BfProject*>& projectList)
|
BfModule* BfModule::GetSpecializedMethodModule(const SizedArrayImpl<BfProject*>& projectList)
|
||||||
{
|
{
|
||||||
BF_ASSERT(!mIsScratchModule);
|
BF_ASSERT(!mIsScratchModule);
|
||||||
BF_ASSERT(mIsReified);
|
BF_ASSERT(mIsReified);
|
||||||
|
@ -8667,7 +8678,7 @@ BfModule* BfModule::GetSpecializedMethodModule(const Array<BfProject*>& projectL
|
||||||
|
|
||||||
BfModule* specModule = NULL;
|
BfModule* specModule = NULL;
|
||||||
BfModule** specModulePtr = NULL;
|
BfModule** specModulePtr = NULL;
|
||||||
if (mainModule->mSpecializedMethodModules.TryGetValue(projectList, &specModulePtr))
|
if (mainModule->mSpecializedMethodModules.TryGetValueWith(projectList, &specModulePtr))
|
||||||
{
|
{
|
||||||
return *specModulePtr;
|
return *specModulePtr;
|
||||||
}
|
}
|
||||||
|
@ -8681,7 +8692,11 @@ BfModule* BfModule::GetSpecializedMethodModule(const Array<BfProject*>& projectL
|
||||||
specModule->mParentModule = mainModule;
|
specModule->mParentModule = mainModule;
|
||||||
specModule->mIsSpecializedMethodModuleRoot = true;
|
specModule->mIsSpecializedMethodModuleRoot = true;
|
||||||
specModule->Init();
|
specModule->Init();
|
||||||
mainModule->mSpecializedMethodModules[projectList] = specModule;
|
|
||||||
|
Array<BfProject*> projList;
|
||||||
|
for (auto project : projectList)
|
||||||
|
projList.Add(project);
|
||||||
|
mainModule->mSpecializedMethodModules[projList] = specModule;
|
||||||
}
|
}
|
||||||
return specModule;
|
return specModule;
|
||||||
}
|
}
|
||||||
|
@ -11080,7 +11095,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
||||||
}
|
}
|
||||||
|
|
||||||
BfTypeVector sanitizedMethodGenericArguments;
|
BfTypeVector sanitizedMethodGenericArguments;
|
||||||
Array<BfProject*> projectList;
|
SizedArray<BfProject*, 4> projectList;
|
||||||
|
|
||||||
bool isUnspecializedPass = (flags & BfGetMethodInstanceFlag_UnspecializedPass) != 0;
|
bool isUnspecializedPass = (flags & BfGetMethodInstanceFlag_UnspecializedPass) != 0;
|
||||||
if ((isUnspecializedPass) && (methodDef->mGenericParams.size() == 0))
|
if ((isUnspecializedPass) && (methodDef->mGenericParams.size() == 0))
|
||||||
|
|
|
@ -833,6 +833,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
BumpAllocator mBumpAlloc;
|
||||||
BfMethodState* mPrevMethodState; // Only non-null for things like local methods
|
BfMethodState* mPrevMethodState; // Only non-null for things like local methods
|
||||||
BfConstResolveState* mConstResolveState;
|
BfConstResolveState* mConstResolveState;
|
||||||
BfMethodInstance* mMethodInstance;
|
BfMethodInstance* mMethodInstance;
|
||||||
|
@ -841,8 +842,8 @@ public:
|
||||||
BfIRBlock mIRHeadBlock;
|
BfIRBlock mIRHeadBlock;
|
||||||
BfIRBlock mIRInitBlock;
|
BfIRBlock mIRInitBlock;
|
||||||
BfIRBlock mIREntryBlock;
|
BfIRBlock mIREntryBlock;
|
||||||
Array<BfLocalVariable*> mLocals;
|
Array<BfLocalVariable*, AllocatorBump<BfLocalVariable*> > mLocals;
|
||||||
HashSet<BfLocalVarEntry> mLocalVarSet;
|
HashSet<BfLocalVarEntry, AllocatorBump<BfLocalVariable*> > mLocalVarSet;
|
||||||
Array<BfLocalMethod*> mLocalMethods;
|
Array<BfLocalMethod*> mLocalMethods;
|
||||||
Dictionary<String, BfLocalMethod*> mLocalMethodMap;
|
Dictionary<String, BfLocalMethod*> mLocalMethodMap;
|
||||||
Dictionary<String, BfLocalMethod*> mLocalMethodCache; // So any lambda 'capturing' and 'processing' stages use the same local method
|
Dictionary<String, BfLocalMethod*> mLocalMethodCache; // So any lambda 'capturing' and 'processing' stages use the same local method
|
||||||
|
@ -900,6 +901,11 @@ public:
|
||||||
public:
|
public:
|
||||||
BfMethodState()
|
BfMethodState()
|
||||||
{
|
{
|
||||||
|
mLocals.mAlloc = &mBumpAlloc;
|
||||||
|
mLocals.Reserve(8);
|
||||||
|
mLocalVarSet.mAlloc = &mBumpAlloc;
|
||||||
|
mLocalVarSet.Reserve(8);
|
||||||
|
|
||||||
mMethodInstance = NULL;
|
mMethodInstance = NULL;
|
||||||
mPrevMethodState = NULL;
|
mPrevMethodState = NULL;
|
||||||
mConstResolveState = NULL;
|
mConstResolveState = NULL;
|
||||||
|
@ -1344,7 +1350,6 @@ public:
|
||||||
bool mIgnoreErrors;
|
bool mIgnoreErrors;
|
||||||
bool mIgnoreWarnings;
|
bool mIgnoreWarnings;
|
||||||
bool mSetIllegalSrcPosition;
|
bool mSetIllegalSrcPosition;
|
||||||
bool mHadIgnoredError;
|
|
||||||
bool mReportErrors; // Still puts system in error state when set to false
|
bool mReportErrors; // Still puts system in error state when set to false
|
||||||
bool mIsInsideAutoComplete;
|
bool mIsInsideAutoComplete;
|
||||||
bool mIsHotModule;
|
bool mIsHotModule;
|
||||||
|
@ -1439,6 +1444,7 @@ public:
|
||||||
BfDeferredCallEntry* AddDeferredCall(const BfModuleMethodInstance& moduleMethodInstance, SizedArrayImpl<BfIRValue>& llvmArgs, BfScopeData* scope, BfAstNode* srcNode = NULL, bool bypassVirtual = false, bool doNullCheck = false);
|
BfDeferredCallEntry* AddDeferredCall(const BfModuleMethodInstance& moduleMethodInstance, SizedArrayImpl<BfIRValue>& llvmArgs, BfScopeData* scope, BfAstNode* srcNode = NULL, bool bypassVirtual = false, bool doNullCheck = false);
|
||||||
void EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry);
|
void EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry);
|
||||||
void EmitDeferredCallProcessor(SLIList<BfDeferredCallEntry*>& callEntries, BfIRValue callTail);
|
void EmitDeferredCallProcessor(SLIList<BfDeferredCallEntry*>& callEntries, BfIRValue callTail);
|
||||||
|
bool DoCanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags = BfCastFlags_None);
|
||||||
bool CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags = BfCastFlags_None);
|
bool CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags = BfCastFlags_None);
|
||||||
bool AreSplatsCompatible(BfType* fromType, BfType* toType, bool* outNeedsMemberCasting);
|
bool AreSplatsCompatible(BfType* fromType, BfType* toType, bool* outNeedsMemberCasting);
|
||||||
BfTypedValue BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfType* toType /*Can be System.Object or interface*/, const BfAllocTarget& allocTarget, bool callDtor = true);
|
BfTypedValue BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfType* toType /*Can be System.Object or interface*/, const BfAllocTarget& allocTarget, bool callDtor = true);
|
||||||
|
@ -1712,7 +1718,7 @@ public:
|
||||||
BfMethodInstance* GetRawMethodByName(BfTypeInstance* typeInstance, const StringImpl& methodName, int paramCount = -1, bool checkBase = false, bool allowMixin = false);
|
BfMethodInstance* GetRawMethodByName(BfTypeInstance* typeInstance, const StringImpl& methodName, int paramCount = -1, bool checkBase = false, bool allowMixin = false);
|
||||||
BfMethodInstance* GetUnspecializedMethodInstance(BfMethodInstance* methodInstance); // Unspecialized owner type and unspecialized method type
|
BfMethodInstance* GetUnspecializedMethodInstance(BfMethodInstance* methodInstance); // Unspecialized owner type and unspecialized method type
|
||||||
int GetGenericParamAndReturnCount(BfMethodInstance* methodInstance);
|
int GetGenericParamAndReturnCount(BfMethodInstance* methodInstance);
|
||||||
BfModule* GetSpecializedMethodModule(const Array<BfProject*>& projectList);
|
BfModule* GetSpecializedMethodModule(const SizedArrayImpl<BfProject*>& projectList);
|
||||||
BfModuleMethodInstance GetMethodInstanceAtIdx(BfTypeInstance* typeInstance, int methodIdx, const char* assertName = NULL);
|
BfModuleMethodInstance GetMethodInstanceAtIdx(BfTypeInstance* typeInstance, int methodIdx, const char* assertName = NULL);
|
||||||
BfModuleMethodInstance GetMethodByName(BfTypeInstance* typeInstance, const StringImpl& methodName, int paramCount = -1, bool checkBase = false);
|
BfModuleMethodInstance GetMethodByName(BfTypeInstance* typeInstance, const StringImpl& methodName, int paramCount = -1, bool checkBase = false);
|
||||||
BfModuleMethodInstance GetMethodByName(BfTypeInstance* typeInstance, const StringImpl& methodName, const Array<BfType*>& paramTypes, bool checkBase = false);
|
BfModuleMethodInstance GetMethodByName(BfTypeInstance* typeInstance, const StringImpl& methodName, const Array<BfType*>& paramTypes, bool checkBase = false);
|
||||||
|
|
|
@ -4653,8 +4653,6 @@ BfBoxedType* BfModule::CreateBoxedType(BfType* resolvedTypeRef)
|
||||||
{
|
{
|
||||||
bool isStructPtr = false;
|
bool isStructPtr = false;
|
||||||
|
|
||||||
// if (resolvedTypeRef->IsPointer())
|
|
||||||
// resolvedTypeRef = ((BfPointerType*)resolvedTypeRef)->mElementType;
|
|
||||||
if (resolvedTypeRef->IsPrimitiveType())
|
if (resolvedTypeRef->IsPrimitiveType())
|
||||||
{
|
{
|
||||||
auto primType = (BfPrimitiveType*)resolvedTypeRef;
|
auto primType = (BfPrimitiveType*)resolvedTypeRef;
|
||||||
|
@ -7696,8 +7694,7 @@ BfType* BfModule::ResolveTypeRef(BfAstNode* astNode, const BfSizedArray<BfTypeRe
|
||||||
return ResolveTypeRef(typeRef, populateType, resolveFlags);
|
return ResolveTypeRef(typeRef, populateType, resolveFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This flow should mirror CastToValue
|
bool BfModule::DoCanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags)
|
||||||
bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags)
|
|
||||||
{
|
{
|
||||||
BfType* fromType = typedVal.mType;
|
BfType* fromType = typedVal.mType;
|
||||||
|
|
||||||
|
@ -7782,7 +7779,7 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl
|
||||||
{
|
{
|
||||||
if ((genericParamInst->mGenericParamFlags & (BfGenericParamFlag_Class | BfGenericParamFlag_StructPtr)) ||
|
if ((genericParamInst->mGenericParamFlags & (BfGenericParamFlag_Class | BfGenericParamFlag_StructPtr)) ||
|
||||||
((genericParamInst->mTypeConstraint != NULL) &&
|
((genericParamInst->mTypeConstraint != NULL) &&
|
||||||
((genericParamInst->mTypeConstraint->IsPointer()) || (genericParamInst->mTypeConstraint->IsObjectOrInterface()))))
|
((genericParamInst->mTypeConstraint->IsPointer()) || (genericParamInst->mTypeConstraint->IsObjectOrInterface()))))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -7868,8 +7865,8 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl
|
||||||
// And from T* to T[size]* explicitly
|
// And from T* to T[size]* explicitly
|
||||||
if (fromUnderlying->IsSizedArray())
|
if (fromUnderlying->IsSizedArray())
|
||||||
fromUnderlying = fromUnderlying->GetUnderlyingType();
|
fromUnderlying = fromUnderlying->GetUnderlyingType();
|
||||||
// if ((toUnderlying->IsSizedArray()) && (explicitCast))
|
// if ((toUnderlying->IsSizedArray()) && (explicitCast))
|
||||||
// toUnderlying = toUnderlying->GetUnderlyingType();
|
// toUnderlying = toUnderlying->GetUnderlyingType();
|
||||||
|
|
||||||
if ((fromUnderlying == toUnderlying) ||
|
if ((fromUnderlying == toUnderlying) ||
|
||||||
(TypeIsSubTypeOf(fromUnderlying->ToTypeInstance(), toUnderlying->ToTypeInstance())) ||
|
(TypeIsSubTypeOf(fromUnderlying->ToTypeInstance(), toUnderlying->ToTypeInstance())) ||
|
||||||
|
@ -7905,20 +7902,20 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl
|
||||||
if (((fromType->IsValueType()) || (fromType->IsPointer()) || (fromType->IsValuelessType())) &&
|
if (((fromType->IsValueType()) || (fromType->IsPointer()) || (fromType->IsValuelessType())) &&
|
||||||
((toType->IsInterface()) || (toType == mContext->mBfObjectType)))
|
((toType->IsInterface()) || (toType == mContext->mBfObjectType)))
|
||||||
{
|
{
|
||||||
// if (fromType->IsPointer())
|
// if (fromType->IsPointer())
|
||||||
// {
|
// {
|
||||||
// if (toType == mContext->mBfObjectType)
|
// if (toType == mContext->mBfObjectType)
|
||||||
// return true;
|
// return true;
|
||||||
// return false;
|
// return false;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if (toType == mContext->mBfObjectType)
|
if (toType == mContext->mBfObjectType)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
BfTypeInstance* fromStructTypeInstance = NULL;
|
BfTypeInstance* fromStructTypeInstance = NULL;
|
||||||
fromStructTypeInstance = fromType->ToTypeInstance();
|
fromStructTypeInstance = fromType->ToTypeInstance();
|
||||||
if (fromStructTypeInstance == NULL)
|
if (fromStructTypeInstance == NULL)
|
||||||
{
|
{
|
||||||
if (fromType->IsPrimitiveType())
|
if (fromType->IsPrimitiveType())
|
||||||
{
|
{
|
||||||
auto primType = (BfPrimitiveType*)fromType;
|
auto primType = (BfPrimitiveType*)fromType;
|
||||||
|
@ -7926,15 +7923,79 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto toTypeInstance = toType->ToTypeInstance();
|
auto toTypeInstance = toType->ToTypeInstance();
|
||||||
// Need to box it
|
// Need to box it
|
||||||
if (TypeIsSubTypeOf(fromStructTypeInstance, toTypeInstance))
|
if (TypeIsSubTypeOf(fromStructTypeInstance, toTypeInstance))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromType->IsRef())
|
// Null -> Nullable<T>
|
||||||
|
if ((typedVal.mType->IsNull()) && (toType->IsNullable()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nullable<A> -> Nullable<B>
|
||||||
|
if ((typedVal.mType->IsNullable()) && (toType->IsNullable()))
|
||||||
|
{
|
||||||
|
auto fromNullableType = (BfGenericTypeInstance*)typedVal.mType;
|
||||||
|
auto toNullableType = (BfGenericTypeInstance*)toType;
|
||||||
|
|
||||||
|
return CanImplicitlyCast(BfTypedValue(mBfIRBuilder->GetFakeVal(), fromNullableType->mTypeGenericArguments[0]), toNullableType->mTypeGenericArguments[0], castFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tuple -> Tuple
|
||||||
|
if ((typedVal.mType->IsTuple()) && (toType->IsTuple()))
|
||||||
|
{
|
||||||
|
auto fromTupleType = (BfTupleType*)typedVal.mType;
|
||||||
|
auto toTupleType = (BfTupleType*)toType;
|
||||||
|
if (fromTupleType->mFieldInstances.size() == toTupleType->mFieldInstances.size())
|
||||||
|
{
|
||||||
|
bool canCast = true;
|
||||||
|
|
||||||
|
BfIRValue curTupleValue = mBfIRBuilder->CreateUndefValue(mBfIRBuilder->MapType(toTupleType));
|
||||||
|
for (int valueIdx = 0; valueIdx < (int)fromTupleType->mFieldInstances.size(); valueIdx++)
|
||||||
|
{
|
||||||
|
BfFieldInstance* fromFieldInstance = &fromTupleType->mFieldInstances[valueIdx];
|
||||||
|
BfFieldInstance* toFieldInstance = &toTupleType->mFieldInstances[valueIdx];
|
||||||
|
|
||||||
|
//
|
||||||
|
{
|
||||||
|
BfFieldDef* fromFieldDef = fromFieldInstance->GetFieldDef();
|
||||||
|
BfFieldDef* toFieldDef = toFieldInstance->GetFieldDef();
|
||||||
|
|
||||||
|
// Either the names have to match or one has to be unnamed
|
||||||
|
if ((!fromFieldDef->IsUnnamedTupleField()) && (!toFieldDef->IsUnnamedTupleField()) &&
|
||||||
|
(fromFieldDef->mName != toFieldDef->mName))
|
||||||
|
{
|
||||||
|
curTupleValue = BfIRValue();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto fromFieldType = fromFieldInstance->GetResolvedType();
|
||||||
|
auto toFieldType = toFieldInstance->GetResolvedType();
|
||||||
|
|
||||||
|
if (toFieldType->IsVoid())
|
||||||
|
continue; // Allow sinking to void
|
||||||
|
|
||||||
|
BfIRValue fromFieldValue;
|
||||||
|
bool canCastField = CanImplicitlyCast(BfTypedValue(mBfIRBuilder->GetFakeVal(), fromFieldType), toFieldType, (BfCastFlags)(castFlags | BfCastFlags_Explicit));
|
||||||
|
if (!canCastField)
|
||||||
|
{
|
||||||
|
canCast = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (canCast)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (fromType->IsRef())
|
||||||
{
|
{
|
||||||
if (toType->IsRef())
|
if (toType->IsRef())
|
||||||
{
|
{
|
||||||
|
@ -7946,7 +8007,7 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl
|
||||||
// ref T -> T
|
// ref T -> T
|
||||||
return fromType->GetUnderlyingType() == toType;
|
return fromType->GetUnderlyingType() == toType;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// Int -> Enum
|
// Int -> Enum
|
||||||
if ((typedVal.mType->IsIntegral()) && (toType->IsEnum()))
|
if ((typedVal.mType->IsIntegral()) && (toType->IsEnum()))
|
||||||
|
@ -8054,15 +8115,15 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl
|
||||||
}
|
}
|
||||||
else if (toType->IsSigned())
|
else if (toType->IsSigned())
|
||||||
{
|
{
|
||||||
if (toType->mSize == 8) // int64
|
if (toType->mSize == 8) // int64
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int64 minVal = -(1LL << (8 * toType->mSize - 1));
|
int64 minVal = -(1LL << (8 * toType->mSize - 1));
|
||||||
int64 maxVal = (1LL << (8 * toType->mSize - 1)) - 1;
|
int64 maxVal = (1LL << (8 * toType->mSize - 1)) - 1;
|
||||||
if ((srcVal >= minVal) && (srcVal <= maxVal))
|
if ((srcVal >= minVal) && (srcVal <= maxVal))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (toType->mSize == 8) // ulong
|
else if (toType->mSize == 8) // ulong
|
||||||
{
|
{
|
||||||
|
@ -8501,7 +8562,7 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl
|
||||||
{
|
{
|
||||||
if ((methodFromType == bestFromType) && (methodToType == bestToType))
|
if ((methodFromType == bestFromType) && (methodToType == bestToType))
|
||||||
{
|
{
|
||||||
return true;
|
return CanImplicitlyCast(BfTypedValue(BfIRValue::sValueless, bestToType), toType, castFlags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8518,9 +8579,56 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prim -> TypedPrimitive
|
||||||
|
if ((typedVal.mType->IsPrimitiveType()) && (toType->IsTypedPrimitive()))
|
||||||
|
{
|
||||||
|
bool allowCast = false;
|
||||||
|
if (toType == mCurTypeInstance)
|
||||||
|
allowCast = true;
|
||||||
|
if ((!allowCast) && (typedVal.mType->IsIntegral()) /*&& (!toType->IsEnum())*/)
|
||||||
|
{
|
||||||
|
// Allow implicit cast of zero
|
||||||
|
auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
|
||||||
|
if ((constant != NULL) && (mBfIRBuilder->IsInt(constant->mTypeCode)))
|
||||||
|
{
|
||||||
|
allowCast = constant->mInt64 == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (allowCast)
|
||||||
|
{
|
||||||
|
return CanImplicitlyCast(typedVal, toType->GetUnderlyingType(), castFlags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This flow should mirror CastToValue
|
||||||
|
bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags)
|
||||||
|
{
|
||||||
|
BP_ZONE("BfModule::CanImplicitlyCast");
|
||||||
|
|
||||||
|
//return DoCanImplicitlyCast(typedVal, toType, castFlags);
|
||||||
|
|
||||||
|
bool canCastToValue;
|
||||||
|
{
|
||||||
|
SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true);
|
||||||
|
canCastToValue = CastToValue(NULL, typedVal, toType, (BfCastFlags)(castFlags | BfCastFlags_SilentFail));
|
||||||
|
return canCastToValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return canCastToValue;
|
||||||
|
|
||||||
|
bool sideCanCast = DoCanImplicitlyCast(typedVal, toType, castFlags);
|
||||||
|
if (canCastToValue != sideCanCast)
|
||||||
|
{
|
||||||
|
NOP;
|
||||||
|
}
|
||||||
|
//BF_ASSERT(canCastToValue == sideCanCast);
|
||||||
|
return sideCanCast;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool BfModule::AreSplatsCompatible(BfType* fromType, BfType* toType, bool* outNeedsMemberCasting)
|
bool BfModule::AreSplatsCompatible(BfType* fromType, BfType* toType, bool* outNeedsMemberCasting)
|
||||||
{
|
{
|
||||||
if ((fromType->IsTypeInstance()) && (!fromType->IsSplattable()))
|
if ((fromType->IsTypeInstance()) && (!fromType->IsSplattable()))
|
||||||
|
@ -8600,6 +8708,8 @@ BfIRValue BfModule::CastToFunction(BfAstNode* srcNode, BfMethodInstance* methodI
|
||||||
BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags, BfCastResultFlags* resultFlags)
|
BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags, BfCastResultFlags* resultFlags)
|
||||||
{
|
{
|
||||||
bool explicitCast = (castFlags & BfCastFlags_Explicit) != 0;
|
bool explicitCast = (castFlags & BfCastFlags_Explicit) != 0;
|
||||||
|
bool ignoreErrors = mIgnoreErrors || ((castFlags & BfCastFlags_SilentFail) != 0);
|
||||||
|
bool ignoreWrites = mBfIRBuilder->mIgnoreWrites;
|
||||||
|
|
||||||
if (typedVal.mType == toType)
|
if (typedVal.mType == toType)
|
||||||
{
|
{
|
||||||
|
@ -8693,11 +8803,10 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
// void* -> intptr
|
// void* -> intptr
|
||||||
if ((typedVal.mType->IsPointer()) && (toType->IsIntPtr()))
|
if ((typedVal.mType->IsPointer()) && (toType->IsIntPtr()))
|
||||||
{
|
{
|
||||||
//TODO: Put back
|
if ((!ignoreErrors) && (!typedVal.mType->GetUnderlyingType()->IsVoid()) && ((castFlags & BfCastFlags_FromCompiler) == 0))
|
||||||
/*if ((!typedVal.mType->GetUnderlyingType()->IsVoid()) && ((castFlags & BfCastFlags_FromCompiler) == 0))
|
|
||||||
{
|
{
|
||||||
Fail(StrFormat("Unable to cast direct from '%s' to '%s', consider casting to void* first", TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode);
|
Fail(StrFormat("Unable to cast direct from '%s' to '%s', consider casting to void* first", TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode);
|
||||||
}*/
|
}
|
||||||
|
|
||||||
auto toPrimitive = (BfPrimitiveType*)toType;
|
auto toPrimitive = (BfPrimitiveType*)toType;
|
||||||
return mBfIRBuilder->CreatePtrToInt(typedVal.mValue, toPrimitive->mTypeDef->mTypeCode);
|
return mBfIRBuilder->CreatePtrToInt(typedVal.mValue, toPrimitive->mTypeDef->mTypeCode);
|
||||||
|
@ -8706,11 +8815,10 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
// intptr -> void*
|
// intptr -> void*
|
||||||
if ((typedVal.mType->IsIntPtr()) && (toType->IsPointer()))
|
if ((typedVal.mType->IsIntPtr()) && (toType->IsPointer()))
|
||||||
{
|
{
|
||||||
//TODO: Put back
|
if ((!ignoreErrors) && (!toType->GetUnderlyingType()->IsVoid()) && ((castFlags & BfCastFlags_FromCompiler) == 0))
|
||||||
/*if ((!toType->GetUnderlyingType()->IsVoid()) && ((castFlags & BfCastFlags_FromCompiler) == 0))
|
|
||||||
{
|
{
|
||||||
Fail(StrFormat("Unable to cast direct from '%s' to '%s', consider casting to void* first", TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode);
|
Fail(StrFormat("Unable to cast direct from '%s' to '%s', consider casting to void* first", TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode);
|
||||||
}*/
|
}
|
||||||
|
|
||||||
return mBfIRBuilder->CreateIntToPtr(typedVal.mValue, mBfIRBuilder->MapType(toType));
|
return mBfIRBuilder->CreateIntToPtr(typedVal.mValue, mBfIRBuilder->MapType(toType));
|
||||||
}
|
}
|
||||||
|
@ -8846,29 +8954,48 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ObjectInst|IFace -> object|IFace
|
if ((typedVal.mType->IsTypeInstance()) && (toType->IsTypeInstance()))
|
||||||
if ((typedVal.mType->IsObject() || (typedVal.mType->IsInterface())) && ((toType->IsObject() || (toType->IsInterface()))))
|
|
||||||
{
|
{
|
||||||
bool allowCast = false;
|
|
||||||
|
|
||||||
auto fromTypeInstance = typedVal.mType->ToTypeInstance();
|
auto fromTypeInstance = typedVal.mType->ToTypeInstance();
|
||||||
auto toTypeInstance = toType->ToTypeInstance();
|
auto toTypeInstance = toType->ToTypeInstance();
|
||||||
|
|
||||||
if (TypeIsSubTypeOf(fromTypeInstance, toTypeInstance))
|
if ((typedVal.mType->IsValueType()) && (toType->IsValueType()))
|
||||||
allowCast = true;
|
|
||||||
else if ((explicitCast) &&
|
|
||||||
((toType->IsInterface()) || (TypeIsSubTypeOf(toTypeInstance, fromTypeInstance))))
|
|
||||||
{
|
{
|
||||||
if (toType->IsObjectOrInterface())
|
bool allowCast = false;
|
||||||
|
if (TypeIsSubTypeOf(fromTypeInstance, toTypeInstance))
|
||||||
|
allowCast = true;
|
||||||
|
if (allowCast)
|
||||||
{
|
{
|
||||||
if ((castFlags & BfCastFlags_Unchecked) == 0)
|
if (toType->IsValuelessType())
|
||||||
EmitDynamicCastCheck(typedVal, toType, true);
|
return BfIRValue::sValueless;
|
||||||
}
|
}
|
||||||
allowCast = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allowCast)
|
// ObjectInst|IFace -> object|IFace
|
||||||
return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
|
if ((typedVal.mType->IsObject() || (typedVal.mType->IsInterface())) && ((toType->IsObject() || (toType->IsInterface()))))
|
||||||
|
{
|
||||||
|
bool allowCast = false;
|
||||||
|
|
||||||
|
if (TypeIsSubTypeOf(fromTypeInstance, toTypeInstance))
|
||||||
|
allowCast = true;
|
||||||
|
else if ((explicitCast) &&
|
||||||
|
((toType->IsInterface()) || (TypeIsSubTypeOf(toTypeInstance, fromTypeInstance))))
|
||||||
|
{
|
||||||
|
if (toType->IsObjectOrInterface())
|
||||||
|
{
|
||||||
|
if ((castFlags & BfCastFlags_Unchecked) == 0)
|
||||||
|
EmitDynamicCastCheck(typedVal, toType, true);
|
||||||
|
}
|
||||||
|
allowCast = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allowCast)
|
||||||
|
{
|
||||||
|
if (ignoreWrites)
|
||||||
|
return mBfIRBuilder->GetFakeVal();
|
||||||
|
return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MethodRef -> Function
|
// MethodRef -> Function
|
||||||
|
@ -8918,7 +9045,11 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
allowCast = true;
|
allowCast = true;
|
||||||
|
|
||||||
if (allowCast)
|
if (allowCast)
|
||||||
|
{
|
||||||
|
if (ignoreWrites)
|
||||||
|
return mBfIRBuilder->GetFakeVal();
|
||||||
return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
|
return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (typedVal.mType->IsObject())
|
else if (typedVal.mType->IsObject())
|
||||||
{
|
{
|
||||||
|
@ -8951,9 +9082,10 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
((toType->IsValueType()) || (toType->IsPointer())))
|
((toType->IsValueType()) || (toType->IsPointer())))
|
||||||
{
|
{
|
||||||
if (toType->IsValuelessType())
|
if (toType->IsValuelessType())
|
||||||
{
|
return BfIRValue::sValueless;
|
||||||
|
|
||||||
|
if (ignoreWrites)
|
||||||
return mBfIRBuilder->GetFakeVal();
|
return mBfIRBuilder->GetFakeVal();
|
||||||
}
|
|
||||||
|
|
||||||
// Unbox!
|
// Unbox!
|
||||||
if ((castFlags & BfCastFlags_Unchecked) == 0)
|
if ((castFlags & BfCastFlags_Unchecked) == 0)
|
||||||
|
@ -9036,6 +9168,9 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
// Null -> Nullable<T>
|
// Null -> Nullable<T>
|
||||||
if ((typedVal.mType->IsNull()) && (toType->IsNullable()))
|
if ((typedVal.mType->IsNull()) && (toType->IsNullable()))
|
||||||
{
|
{
|
||||||
|
if (ignoreWrites)
|
||||||
|
return mBfIRBuilder->GetFakeVal();
|
||||||
|
|
||||||
if ((castFlags & BfCastFlags_PreferAddr) != 0)
|
if ((castFlags & BfCastFlags_PreferAddr) != 0)
|
||||||
{
|
{
|
||||||
auto boolType = GetPrimitiveType(BfTypeCode_Boolean);
|
auto boolType = GetPrimitiveType(BfTypeCode_Boolean);
|
||||||
|
@ -9059,6 +9194,9 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
// Nullable<A> -> Nullable<B>
|
// Nullable<A> -> Nullable<B>
|
||||||
if ((typedVal.mType->IsNullable()) && (toType->IsNullable()))
|
if ((typedVal.mType->IsNullable()) && (toType->IsNullable()))
|
||||||
{
|
{
|
||||||
|
if (ignoreWrites)
|
||||||
|
return mBfIRBuilder->GetFakeVal();
|
||||||
|
|
||||||
auto fromNullableType = (BfGenericTypeInstance*)typedVal.mType;
|
auto fromNullableType = (BfGenericTypeInstance*)typedVal.mType;
|
||||||
auto toNullableType = (BfGenericTypeInstance*)toType;
|
auto toNullableType = (BfGenericTypeInstance*)toType;
|
||||||
|
|
||||||
|
@ -9073,7 +9211,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
auto srcAddr = mBfIRBuilder->CreateInBoundsGEP(srcPtr, 0, 1); // mValue
|
auto srcAddr = mBfIRBuilder->CreateInBoundsGEP(srcPtr, 0, 1); // mValue
|
||||||
auto srcVal = mBfIRBuilder->CreateLoad(srcAddr);
|
auto srcVal = mBfIRBuilder->CreateLoad(srcAddr);
|
||||||
|
|
||||||
auto toVal = CastToValue(srcNode, BfTypedValue(srcVal, fromNullableType->mTypeGenericArguments[0]), toNullableType->mTypeGenericArguments[0]);
|
auto toVal = CastToValue(srcNode, BfTypedValue(srcVal, fromNullableType->mTypeGenericArguments[0]), toNullableType->mTypeGenericArguments[0], ignoreErrors ? BfCastFlags_SilentFail : BfCastFlags_None);
|
||||||
if (!toVal)
|
if (!toVal)
|
||||||
return BfIRValue();
|
return BfIRValue();
|
||||||
|
|
||||||
|
@ -9166,7 +9304,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
return typedVal.mValue;
|
return typedVal.mValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((castFlags & BfCastFlags_SilentFail) == 0)
|
if (!ignoreErrors)
|
||||||
{
|
{
|
||||||
String valStr;
|
String valStr;
|
||||||
VariantToString(valStr, variantVal);
|
VariantToString(valStr, variantVal);
|
||||||
|
@ -9533,7 +9671,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
if (fromDist < 0)
|
if (fromDist < 0)
|
||||||
{
|
{
|
||||||
// Allow us to cast a constant int to a smaller type if it satisfies the cast operator
|
// Allow us to cast a constant int to a smaller type if it satisfies the cast operator
|
||||||
if ((typedVal.mValue.IsConst()) && (CanImplicitlyCast(typedVal, methodCheckFromType)))
|
if ((typedVal.mValue.IsConst()) && (CanImplicitlyCast(typedVal, methodCheckFromType, BfCastFlags_NoConversionOperator)))
|
||||||
{
|
{
|
||||||
fromDist = 0;
|
fromDist = 0;
|
||||||
}
|
}
|
||||||
|
@ -9623,7 +9761,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
{
|
{
|
||||||
if (mayBeBox)
|
if (mayBeBox)
|
||||||
{
|
{
|
||||||
if (Fail("Ambiguous cast, may be conversion operator or may be boxing request", srcNode) != NULL)
|
if ((!ignoreErrors) && (Fail("Ambiguous cast, may be conversion operator or may be boxing request", srcNode) != NULL))
|
||||||
mCompiler->mPassInstance->MoreInfo("See conversion operator", opMethodInstance->mMethodDef->GetRefNode());
|
mCompiler->mPassInstance->MoreInfo("See conversion operator", opMethodInstance->mMethodDef->GetRefNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9654,6 +9792,9 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
if (!castedFromValue)
|
if (!castedFromValue)
|
||||||
return BfIRValue();
|
return BfIRValue();
|
||||||
|
|
||||||
|
if (ignoreWrites)
|
||||||
|
return mBfIRBuilder->GetFakeVal();
|
||||||
|
|
||||||
SizedArray<BfIRValue, 1> args;
|
SizedArray<BfIRValue, 1> args;
|
||||||
exprEvaluator.PushArg(castedFromValue, args);
|
exprEvaluator.PushArg(castedFromValue, args);
|
||||||
auto operatorOut = exprEvaluator.CreateCall(moduleMethodInstance.mMethodInstance, mCompiler->IsSkippingExtraResolveChecks() ? BfIRValue() : moduleMethodInstance.mFunc, false, args);
|
auto operatorOut = exprEvaluator.CreateCall(moduleMethodInstance.mMethodInstance, mCompiler->IsSkippingExtraResolveChecks() ? BfIRValue() : moduleMethodInstance.mFunc, false, args);
|
||||||
|
@ -9676,8 +9817,11 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
isAmbiguousCast |= ((bestFromType != NULL) && (bestToType != NULL));
|
isAmbiguousCast |= ((bestFromType != NULL) && (bestToType != NULL));
|
||||||
if (isAmbiguousCast)
|
if (isAmbiguousCast)
|
||||||
{
|
{
|
||||||
const char* errStr = "Ambiguous conversion operators for casting from '%s' to '%s'";
|
if (!ignoreErrors)
|
||||||
Fail(StrFormat(errStr, TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode);
|
{
|
||||||
|
const char* errStr = "Ambiguous conversion operators for casting from '%s' to '%s'";
|
||||||
|
Fail(StrFormat(errStr, TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode);
|
||||||
|
}
|
||||||
return BfIRValue();
|
return BfIRValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9697,7 +9841,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
{
|
{
|
||||||
// .. and we can convert the constraint's toType to OUR toType then we're good
|
// .. and we can convert the constraint's toType to OUR toType then we're good
|
||||||
auto opToVal = genericParam->mExternType;
|
auto opToVal = genericParam->mExternType;
|
||||||
if (CanImplicitlyCast(opToVal, toType))
|
if (CanImplicitlyCast(BfTypedValue(BfIRValue::sValueless, opToVal), toType))
|
||||||
return mBfIRBuilder->GetFakeVal();
|
return mBfIRBuilder->GetFakeVal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9722,7 +9866,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
{
|
{
|
||||||
// .. and we can convert the constraint's toType to OUR toType then we're good
|
// .. and we can convert the constraint's toType to OUR toType then we're good
|
||||||
auto opToVal = genericParam->mExternType;
|
auto opToVal = genericParam->mExternType;
|
||||||
if (CanImplicitlyCast(opToVal, toType))
|
if (CanImplicitlyCast(BfTypedValue(BfIRValue::sValueless, opToVal), toType))
|
||||||
return mBfIRBuilder->GetFakeVal();
|
return mBfIRBuilder->GetFakeVal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9777,7 +9921,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
bool allowCast = explicitCast;
|
bool allowCast = explicitCast;
|
||||||
if (toType == mCurTypeInstance)
|
if (toType == mCurTypeInstance)
|
||||||
allowCast = true;
|
allowCast = true;
|
||||||
if ((!allowCast) && (typedVal.mType->IsIntegral()) && (!toType->IsEnum()))
|
if ((!allowCast) && (typedVal.mType->IsIntegral()) /*&& (!toType->IsEnum())*/)
|
||||||
{
|
{
|
||||||
// Allow implicit cast of zero
|
// Allow implicit cast of zero
|
||||||
auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
|
auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
|
||||||
|
@ -9803,16 +9947,14 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
||||||
Warn(0, "This implicit boxing will only be in scope during the constructor. Consider using a longer-term allocation such as 'box new'", srcNode);
|
Warn(0, "This implicit boxing will only be in scope during the constructor. Consider using a longer-term allocation such as 'box new'", srcNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetAndRestoreValue<bool> ignoreWrites(mBfIRBuilder->mIgnoreWrites, ignoreWrites);
|
||||||
auto value = BoxValue(srcNode, typedVal, toType, scopeData, (castFlags & BfCastFlags_NoBoxDtor) == 0);
|
auto value = BoxValue(srcNode, typedVal, toType, scopeData, (castFlags & BfCastFlags_NoBoxDtor) == 0);
|
||||||
if (value)
|
if (value)
|
||||||
return value.mValue;
|
return value.mValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((castFlags & BfCastFlags_SilentFail) == 0)
|
if (!ignoreErrors)
|
||||||
{
|
{
|
||||||
if (mIgnoreErrors)
|
|
||||||
return BfIRValue();
|
|
||||||
|
|
||||||
const char* errStrF = explicitCast ?
|
const char* errStrF = explicitCast ?
|
||||||
"Unable to cast '%s' to '%s'" :
|
"Unable to cast '%s' to '%s'" :
|
||||||
"Unable to implicitly cast '%s' to '%s'";
|
"Unable to implicitly cast '%s' to '%s'";
|
||||||
|
@ -10526,44 +10668,156 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF
|
||||||
{
|
{
|
||||||
BfTypeInstance* typeInstance = (BfTypeInstance*)resolvedType;
|
BfTypeInstance* typeInstance = (BfTypeInstance*)resolvedType;
|
||||||
|
|
||||||
auto checkTypeInst = typeInstance;
|
//auto checkTypeInst = typeInstance;
|
||||||
auto checkTypeDef = typeInstance->mTypeDef;
|
//auto checkTypeDef = typeInstance->mTypeDef;
|
||||||
|
|
||||||
auto checkCurTypeInst = mCurTypeInstance; // Only used for ReduceName
|
bool omitNamespace = (typeNameFlags & BfTypeNameFlag_OmitNamespace) != 0;
|
||||||
BfTypeDef* checkCurTypeDef = NULL;
|
if ((typeNameFlags & BfTypeNameFlag_ReduceName) != 0)
|
||||||
if (checkCurTypeInst != NULL)
|
|
||||||
checkCurTypeDef = checkCurTypeInst->mTypeDef;
|
|
||||||
|
|
||||||
std::function<void(BfTypeDef*, int)> _AddTypeName = [&](BfTypeDef* checkTypeDef, int depth)
|
|
||||||
{
|
{
|
||||||
if (depth > 0)
|
for (auto& checkNamespace : mCurTypeInstance->mTypeDef->mNamespaceSearch)
|
||||||
{
|
{
|
||||||
if ((typeNameFlags & BfTypeNameFlag_OmitOuterType) != 0)
|
if (checkNamespace == typeInstance->mTypeDef->mNamespace)
|
||||||
return;
|
omitNamespace = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((typeNameFlags & BfTypeNameFlag_ReduceName) != 0)
|
if ((!typeInstance->mTypeDef->mNamespace.IsEmpty()) && (!omitNamespace))
|
||||||
|
{
|
||||||
|
if (!typeInstance->mTypeDef->mNamespace.IsEmpty())
|
||||||
|
{
|
||||||
|
typeInstance->mTypeDef->mNamespace.ToString(str);
|
||||||
|
if (!typeInstance->mTypeDef->IsGlobalsContainer())
|
||||||
|
str += '.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//_AddTypeName(typeInstance->mTypeDef, 0);
|
||||||
|
|
||||||
|
//std::function<void(String& str, BfTypeInstance*, BfTypeDef*, int, BfTypeNameFlags)> _AddTypeName = [&](StringImpl& str, BfTypeInstance*& checkTypeInst, BfTypeDef* checkTypeDef, int depth, BfTypeNameFlags typeNameFlags)
|
||||||
|
|
||||||
|
// BfTypeDef* endTypeDef = NULL;
|
||||||
|
// if ((typeNameFlags & BfTypeNameFlag_ReduceName) != 0)
|
||||||
|
// {
|
||||||
|
// auto checkTypeInst = typeInstance;
|
||||||
|
// auto checkTypeDef = typeInstance->mTypeDef;
|
||||||
|
//
|
||||||
|
// auto outerTypeInst = GetOuterType(checkTypeInst);
|
||||||
|
// if (outerTypeInst == NULL)
|
||||||
|
// return;
|
||||||
|
// checkTypeInst = outerTypeInst;
|
||||||
|
//
|
||||||
|
// auto checkCurTypeInst = mCurTypeInstance; // Only used for ReduceName
|
||||||
|
// BfTypeDef* checkCurTypeDef = NULL;
|
||||||
|
// if (checkCurTypeInst != NULL)
|
||||||
|
// checkCurTypeDef = checkCurTypeInst->mTypeDef;
|
||||||
|
//
|
||||||
|
// while (checkCurTypeDef->mNestDepth > checkTypeDef->mNestDepth)
|
||||||
|
// {
|
||||||
|
// checkCurTypeInst = GetOuterType(checkCurTypeInst);
|
||||||
|
// checkCurTypeDef = checkCurTypeInst->mTypeDef;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (TypeIsSubTypeOf(checkCurTypeInst, checkTypeInst))
|
||||||
|
// endTypeDef = checkCurTypeDef;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SizedArray<BfTypeDef*, 8> typeDefStack;
|
||||||
|
|
||||||
|
BfTypeDef* endTypeDef = NULL;
|
||||||
|
if (((typeNameFlags & BfTypeNameFlag_ReduceName) != 0) && (mCurTypeInstance != NULL))
|
||||||
|
{
|
||||||
|
auto checkTypeInst = typeInstance;
|
||||||
|
|
||||||
|
auto outerTypeInst = GetOuterType(checkTypeInst);
|
||||||
|
if (outerTypeInst != NULL)
|
||||||
|
{
|
||||||
|
checkTypeInst = outerTypeInst;
|
||||||
|
auto checkTypeDef = checkTypeInst->mTypeDef;
|
||||||
|
|
||||||
|
auto checkCurTypeInst = mCurTypeInstance; // Only used for ReduceName
|
||||||
|
BfTypeDef* checkCurTypeDef = NULL;
|
||||||
|
if (checkCurTypeInst != NULL)
|
||||||
|
checkCurTypeDef = checkCurTypeInst->mTypeDef;
|
||||||
|
|
||||||
|
while (checkCurTypeDef->mNestDepth > checkTypeDef->mNestDepth)
|
||||||
{
|
{
|
||||||
auto outerTypeInst = GetOuterType(checkTypeInst);
|
checkCurTypeInst = GetOuterType(checkCurTypeInst);
|
||||||
if (outerTypeInst == NULL)
|
checkCurTypeDef = checkCurTypeInst->mTypeDef;
|
||||||
return;
|
}
|
||||||
checkTypeInst = outerTypeInst;
|
|
||||||
|
|
||||||
while (checkCurTypeDef->mNestDepth > checkTypeDef->mNestDepth)
|
while (checkTypeDef != NULL)
|
||||||
|
{
|
||||||
|
if (TypeIsSubTypeOf(checkCurTypeInst, checkTypeInst))
|
||||||
{
|
{
|
||||||
checkCurTypeInst = GetOuterType(checkCurTypeInst);
|
endTypeDef = checkTypeDef;
|
||||||
checkCurTypeDef = checkCurTypeInst->mTypeDef;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TypeIsSubTypeOf(checkCurTypeInst, checkTypeInst))
|
checkCurTypeInst = GetOuterType(checkCurTypeInst);
|
||||||
return; // Found outer type
|
if (checkCurTypeInst == NULL)
|
||||||
|
break;
|
||||||
|
checkCurTypeDef = checkCurTypeInst->mTypeDef;
|
||||||
|
|
||||||
|
checkTypeInst = GetOuterType(checkTypeInst);
|
||||||
|
if (checkTypeInst == NULL)
|
||||||
|
break;
|
||||||
|
checkTypeDef = checkTypeInst->mTypeDef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto parentTypeDef = checkTypeDef->mOuterType;
|
BfTypeDef* checkTypeDef = typeInstance->mTypeDef;
|
||||||
if (parentTypeDef != NULL)
|
while (checkTypeDef != NULL)
|
||||||
{
|
{
|
||||||
_AddTypeName(parentTypeDef, depth + 1);
|
typeDefStack.Add(checkTypeDef);
|
||||||
}
|
|
||||||
|
checkTypeDef = checkTypeDef->mOuterType;
|
||||||
|
|
||||||
|
if ((typeNameFlags & BfTypeNameFlag_OmitOuterType) != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (checkTypeDef == endTypeDef)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!typeDefStack.IsEmpty())
|
||||||
|
{
|
||||||
|
BfTypeDef* checkTypeDef = typeDefStack.back();
|
||||||
|
int depth = (int)typeDefStack.size() - 1;
|
||||||
|
typeDefStack.pop_back();
|
||||||
|
|
||||||
|
// if (depth > 0)
|
||||||
|
// {
|
||||||
|
// if ((typeNameFlags & BfTypeNameFlag_OmitOuterType) != 0)
|
||||||
|
// return;
|
||||||
|
//
|
||||||
|
// if ((typeNameFlags & BfTypeNameFlag_ReduceName) != 0)
|
||||||
|
// {
|
||||||
|
// auto outerTypeInst = GetOuterType(checkTypeInst);
|
||||||
|
// if (outerTypeInst == NULL)
|
||||||
|
// return;
|
||||||
|
// checkTypeInst = outerTypeInst;
|
||||||
|
//
|
||||||
|
// while (checkCurTypeDef->mNestDepth > checkTypeDef->mNestDepth)
|
||||||
|
// {
|
||||||
|
// checkCurTypeInst = GetOuterType(checkCurTypeInst);
|
||||||
|
// checkCurTypeDef = checkCurTypeInst->mTypeDef;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (TypeIsSubTypeOf(checkCurTypeInst, checkTypeInst))
|
||||||
|
// return; // Found outer type
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// auto parentTypeDef = checkTypeDef->mOuterType;
|
||||||
|
// if (parentTypeDef != NULL)
|
||||||
|
// {
|
||||||
|
// //_AddTypeName(parentTypeDef, depth + 1);
|
||||||
|
// typeDefStack.Add(parentTypeDef);
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
if (checkTypeDef->IsGlobalsContainer())
|
if (checkTypeDef->IsGlobalsContainer())
|
||||||
{
|
{
|
||||||
|
@ -10636,26 +10890,6 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF
|
||||||
str += '.';
|
str += '.';
|
||||||
};
|
};
|
||||||
|
|
||||||
bool omitNamespace = (typeNameFlags & BfTypeNameFlag_OmitNamespace) != 0;
|
|
||||||
if ((typeNameFlags & BfTypeNameFlag_ReduceName) != 0)
|
|
||||||
{
|
|
||||||
for (auto& checkNamespace : mCurTypeInstance->mTypeDef->mNamespaceSearch)
|
|
||||||
{
|
|
||||||
if (checkNamespace == typeInstance->mTypeDef->mNamespace)
|
|
||||||
omitNamespace = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!typeInstance->mTypeDef->mNamespace.IsEmpty()) && (!omitNamespace))
|
|
||||||
{
|
|
||||||
if (!typeInstance->mTypeDef->mNamespace.IsEmpty())
|
|
||||||
{
|
|
||||||
typeInstance->mTypeDef->mNamespace.ToString(str);
|
|
||||||
if (!typeInstance->mTypeDef->IsGlobalsContainer())
|
|
||||||
str += '.';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_AddTypeName(typeInstance->mTypeDef, 0);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (resolvedType->IsPrimitiveType())
|
else if (resolvedType->IsPrimitiveType())
|
||||||
|
|
|
@ -3627,64 +3627,6 @@ String BfTypeUtils::HashEncode64(uint64 val)
|
||||||
return outStr;
|
return outStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfTypeUtils::GetProjectList(BfType* checkType, Array<BfProject*>* projectList, int immutableLength)
|
|
||||||
{
|
|
||||||
if (checkType->IsBoxed())
|
|
||||||
GetProjectList(((BfBoxedType*)checkType)->mElementType, projectList, immutableLength);
|
|
||||||
|
|
||||||
BfTypeInstance* typeInst = checkType->ToTypeInstance();
|
|
||||||
if (typeInst != NULL)
|
|
||||||
{
|
|
||||||
auto genericTypeInst = typeInst->ToGenericTypeInstance();
|
|
||||||
if (genericTypeInst != NULL)
|
|
||||||
{
|
|
||||||
for (auto genericArg : genericTypeInst->mTypeGenericArguments)
|
|
||||||
GetProjectList(genericArg, projectList, immutableLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
BfProject* bfProject = typeInst->mTypeDef->mProject;
|
|
||||||
if (std::find(projectList->begin(), projectList->end(), bfProject) == projectList->end())
|
|
||||||
{
|
|
||||||
bool handled = false;
|
|
||||||
for (int idx = 0; idx < (int)projectList->size(); idx++)
|
|
||||||
{
|
|
||||||
auto checkProject = (*projectList)[idx];
|
|
||||||
bool isBetter = bfProject->ContainsReference(checkProject);
|
|
||||||
bool isWorse = checkProject->ContainsReference(bfProject);
|
|
||||||
if (isBetter == isWorse)
|
|
||||||
continue;
|
|
||||||
if (isBetter)
|
|
||||||
{
|
|
||||||
if (idx >= immutableLength)
|
|
||||||
{
|
|
||||||
// This is even more specific, so replace with this one
|
|
||||||
(*projectList)[idx] = bfProject;
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// This is less specific, ignore
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!handled)
|
|
||||||
{
|
|
||||||
projectList->push_back(bfProject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (checkType->IsPointer())
|
|
||||||
GetProjectList(((BfPointerType*)checkType)->mElementType, projectList, immutableLength);
|
|
||||||
else if (checkType->IsRef())
|
|
||||||
GetProjectList(((BfPointerType*)checkType)->mElementType, projectList, immutableLength);
|
|
||||||
else if (checkType->IsSizedArray())
|
|
||||||
GetProjectList(((BfSizedArrayType*)checkType)->mElementType, projectList, immutableLength);
|
|
||||||
else if (checkType->IsMethodRef())
|
|
||||||
GetProjectList(((BfMethodRefType*)checkType)->mOwner, projectList, immutableLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
BfPrimitiveType* BfTypeUtils::GetPrimitiveType(BfModule* module, BfTypeCode typeCode)
|
BfPrimitiveType* BfTypeUtils::GetPrimitiveType(BfModule* module, BfTypeCode typeCode)
|
||||||
{
|
{
|
||||||
return module->GetPrimitiveType(typeCode);
|
return module->GetPrimitiveType(typeCode);
|
||||||
|
|
|
@ -2332,7 +2332,64 @@ public:
|
||||||
static bool TypeToString(StringImpl& str, BfTypeDef* typeDef, BfTypeNameFlags typeNameFlags = BfTypeNameFlags_None);
|
static bool TypeToString(StringImpl& str, BfTypeDef* typeDef, BfTypeNameFlags typeNameFlags = BfTypeNameFlags_None);
|
||||||
static bool TypeEquals(BfType* typeA, BfType* typeB, BfType* selfType);
|
static bool TypeEquals(BfType* typeA, BfType* typeB, BfType* selfType);
|
||||||
|
|
||||||
static void GetProjectList(BfType* checkType, Array<BfProject*>* projectVector, int immutableLength);
|
template <typename T>
|
||||||
|
static void GetProjectList(BfType* checkType, T* projectList, int immutableLength)
|
||||||
|
{
|
||||||
|
if (checkType->IsBoxed())
|
||||||
|
GetProjectList(((BfBoxedType*)checkType)->mElementType, projectList, immutableLength);
|
||||||
|
|
||||||
|
BfTypeInstance* typeInst = checkType->ToTypeInstance();
|
||||||
|
if (typeInst != NULL)
|
||||||
|
{
|
||||||
|
auto genericTypeInst = typeInst->ToGenericTypeInstance();
|
||||||
|
if (genericTypeInst != NULL)
|
||||||
|
{
|
||||||
|
for (auto genericArg : genericTypeInst->mTypeGenericArguments)
|
||||||
|
GetProjectList(genericArg, projectList, immutableLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
BfProject* bfProject = typeInst->mTypeDef->mProject;
|
||||||
|
if (!projectList->Contains(bfProject))
|
||||||
|
{
|
||||||
|
bool handled = false;
|
||||||
|
for (int idx = 0; idx < (int)projectList->size(); idx++)
|
||||||
|
{
|
||||||
|
auto checkProject = (*projectList)[idx];
|
||||||
|
bool isBetter = bfProject->ContainsReference(checkProject);
|
||||||
|
bool isWorse = checkProject->ContainsReference(bfProject);
|
||||||
|
if (isBetter == isWorse)
|
||||||
|
continue;
|
||||||
|
if (isBetter)
|
||||||
|
{
|
||||||
|
if (idx >= immutableLength)
|
||||||
|
{
|
||||||
|
// This is even more specific, so replace with this one
|
||||||
|
(*projectList)[idx] = bfProject;
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// This is less specific, ignore
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!handled)
|
||||||
|
{
|
||||||
|
projectList->Add(bfProject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (checkType->IsPointer())
|
||||||
|
GetProjectList(((BfPointerType*)checkType)->mElementType, projectList, immutableLength);
|
||||||
|
else if (checkType->IsRef())
|
||||||
|
GetProjectList(((BfPointerType*)checkType)->mElementType, projectList, immutableLength);
|
||||||
|
else if (checkType->IsSizedArray())
|
||||||
|
GetProjectList(((BfSizedArrayType*)checkType)->mElementType, projectList, immutableLength);
|
||||||
|
else if (checkType->IsMethodRef())
|
||||||
|
GetProjectList(((BfMethodRefType*)checkType)->mOwner, projectList, immutableLength);
|
||||||
|
}
|
||||||
|
|
||||||
static BfPrimitiveType* GetPrimitiveType(BfModule* module, BfTypeCode typeCode);
|
static BfPrimitiveType* GetPrimitiveType(BfModule* module, BfTypeCode typeCode);
|
||||||
static void PopulateType(BfModule* module, BfType* type);
|
static void PopulateType(BfModule* module, BfType* type);
|
||||||
|
|
|
@ -1162,7 +1162,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
|
||||||
BfLocalVariable* localDef = new BfLocalVariable();
|
BfLocalVariable* localDef = new BfLocalVariable();
|
||||||
if (varDecl->mNameNode != NULL)
|
if (varDecl->mNameNode != NULL)
|
||||||
{
|
{
|
||||||
localDef->mName = varDecl->mNameNode->ToString();
|
varDecl->mNameNode->ToString(localDef->mName);
|
||||||
localDef->mNameNode = BfNodeDynCast<BfIdentifierNode>(varDecl->mNameNode);
|
localDef->mNameNode = BfNodeDynCast<BfIdentifierNode>(varDecl->mNameNode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1773,7 +1773,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
|
||||||
|
|
||||||
BfLocalVariable* localDef = new BfLocalVariable();
|
BfLocalVariable* localDef = new BfLocalVariable();
|
||||||
if (varDecl->mNameNode != NULL)
|
if (varDecl->mNameNode != NULL)
|
||||||
localDef->mName = varDecl->mNameNode->ToString();
|
varDecl->mNameNode->ToString(localDef->mName);
|
||||||
localDef->mNameNode = BfNodeDynCast<BfIdentifierNode>(varDecl->mNameNode);
|
localDef->mNameNode = BfNodeDynCast<BfIdentifierNode>(varDecl->mNameNode);
|
||||||
localDef->mResolvedType = type;
|
localDef->mResolvedType = type;
|
||||||
localDef->mIsAssigned = true;
|
localDef->mIsAssigned = true;
|
||||||
|
@ -1906,7 +1906,7 @@ void BfModule::HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl, Bf
|
||||||
bool initHandled = false;
|
bool initHandled = false;
|
||||||
|
|
||||||
BfLocalVariable* localDef = new BfLocalVariable();
|
BfLocalVariable* localDef = new BfLocalVariable();
|
||||||
localDef->mName = varNameNode->ToString();
|
varNameNode->ToString(localDef->mName);
|
||||||
localDef->mNameNode = BfNodeDynCast<BfIdentifierNode>(varNameNode);
|
localDef->mNameNode = BfNodeDynCast<BfIdentifierNode>(varNameNode);
|
||||||
localDef->mResolvedType = resolvedType;
|
localDef->mResolvedType = resolvedType;
|
||||||
localDef->mReadFromId = 0; // Don't give usage errors for binds
|
localDef->mReadFromId = 0; // Don't give usage errors for binds
|
||||||
|
@ -2326,9 +2326,9 @@ BfTypedValue BfModule::TryCaseEnumMatch(BfTypedValue enumVal, BfTypedValue tagVa
|
||||||
auto enumType = targetType->ToTypeInstance();
|
auto enumType = targetType->ToTypeInstance();
|
||||||
PopulateType(enumType);
|
PopulateType(enumType);
|
||||||
|
|
||||||
String enumCaseName;
|
StringT<128> enumCaseName;
|
||||||
if (nameNode != NULL)
|
if (nameNode != NULL)
|
||||||
enumCaseName = nameNode->ToString();
|
nameNode->ToString(enumCaseName);
|
||||||
|
|
||||||
auto tagType = GetPrimitiveType(BfTypeCode_Int32);
|
auto tagType = GetPrimitiveType(BfTypeCode_Int32);
|
||||||
if (enumVal.mType != enumType)
|
if (enumVal.mType != enumType)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
@ -218,7 +218,7 @@
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>BP_DISABLED;WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<AdditionalIncludeDirectories>../;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm-project_8_0_1\llvm\include;..\extern\llvm_win64_8_0_1\include;..\extern\llvm-project_8_0_1\llvm\lib\Target;..\extern\llvm_win64_8_0_1\lib\Target\X86;..\extern\llvm-project_8_0_1\llvm\tools\clang\include;..\extern\curl\builds\libcurl-vc15-x64-release-static-zlib-static-ipv6-sspi-winssl\include</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>../;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm-project_8_0_1\llvm\include;..\extern\llvm_win64_8_0_1\include;..\extern\llvm-project_8_0_1\llvm\lib\Target;..\extern\llvm_win64_8_0_1\lib\Target\X86;..\extern\llvm-project_8_0_1\llvm\tools\clang\include;..\extern\curl\builds\libcurl-vc15-x64-release-static-zlib-static-ipv6-sspi-winssl\include</AdditionalIncludeDirectories>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue