From 098ad1ce5571815a87cf1fcfe16e04de8b1bba8d Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 19 Nov 2019 09:58:35 -0800 Subject: [PATCH] Optimizations, switching CanImplicitlyCast method, new CPU rate checker --- BeefLibs/corlib/src/Event.bf | 8 +- BeefLibs/corlib/src/IO/FolderBrowserDialog.bf | 2 +- BeefLibs/corlib/src/IO/OpenFileDialog.bf | 2 +- BeefLibs/corlib/src/Object.bf | 4 +- BeefLibs/corlib/src/Pointer.bf | 2 +- BeefTools/BeefPerf/src/BPClient.bf | 2 +- BeefySysLib/platform/win/Platform.cpp | 43 +- BeefySysLib/util/Array.h | 4 +- BeefySysLib/util/BeefPerf.cpp | 2 +- BeefySysLib/util/BumpAllocator.h | 19 +- BeefySysLib/util/ChunkedDataBuffer.cpp | 36 ++ BeefySysLib/util/ChunkedDataBuffer.h | 3 + BeefySysLib/util/HashSet.h | 32 +- BeefySysLib/util/SizedArray.h | 29 +- IDEHelper/Compiler/BfExprEvaluator.cpp | 34 +- IDEHelper/Compiler/BfIRBuilder.cpp | 108 +++- IDEHelper/Compiler/BfIRBuilder.h | 4 +- IDEHelper/Compiler/BfMangler.cpp | 10 +- IDEHelper/Compiler/BfModule.cpp | 73 ++- IDEHelper/Compiler/BfModule.h | 18 +- IDEHelper/Compiler/BfModuleTypeUtils.cpp | 494 +++++++++++++----- IDEHelper/Compiler/BfResolvedTypeUtils.cpp | 58 -- IDEHelper/Compiler/BfResolvedTypeUtils.h | 59 ++- IDEHelper/Compiler/BfStmtEvaluator.cpp | 10 +- IDEHelper/IDEHelper.vcxproj | 4 +- 25 files changed, 759 insertions(+), 301 deletions(-) diff --git a/BeefLibs/corlib/src/Event.bf b/BeefLibs/corlib/src/Event.bf index 2e512c4f..0e5941dc 100644 --- a/BeefLibs/corlib/src/Event.bf +++ b/BeefLibs/corlib/src/Event.bf @@ -51,7 +51,7 @@ namespace System { if (mData & sIsEnumerating != 0) { - Enumerator* enumerator = (Enumerator*)(mData & sDataMask); + Enumerator* enumerator = (Enumerator*)(void*)(mData & sDataMask); return enumerator.[Friend]mTarget; } return Internal.UnsafeCastToObject((void*)mData); @@ -61,7 +61,7 @@ namespace System { if (mData & sIsEnumerating != 0) { - Enumerator* enumerator = (Enumerator*)(mData & sDataMask); + Enumerator* enumerator = (Enumerator*)(void*)(mData & sDataMask); enumerator.[Friend]mTarget = value; } else @@ -249,12 +249,12 @@ namespace System if (mEvent.mData & sIsEnumerating == 0) { mTarget = mEvent.Target; - mEvent.mData = (int)(&this) | sIsEnumerating; + mEvent.mData = (int)(void*)(&this) | sIsEnumerating; mRootEnumerator = &this; } else { - mRootEnumerator = (Enumerator*)(mEvent.mData & Event.sDataMask); + mRootEnumerator = (Enumerator*)(void*)(mEvent.mData & Event.sDataMask); } mIdx = -1; } diff --git a/BeefLibs/corlib/src/IO/FolderBrowserDialog.bf b/BeefLibs/corlib/src/IO/FolderBrowserDialog.bf index d529e0ee..206c5e38 100644 --- a/BeefLibs/corlib/src/IO/FolderBrowserDialog.bf +++ b/BeefLibs/corlib/src/IO/FolderBrowserDialog.bf @@ -145,7 +145,7 @@ namespace System.IO if (sCurrentThis.mSelectedPath.Length != 0) { // 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; case Windows.BFFM_SELCHANGED: diff --git a/BeefLibs/corlib/src/IO/OpenFileDialog.bf b/BeefLibs/corlib/src/IO/OpenFileDialog.bf index 51a4aa00..2a3cc202 100644 --- a/BeefLibs/corlib/src/IO/OpenFileDialog.bf +++ b/BeefLibs/corlib/src/IO/OpenFileDialog.bf @@ -438,7 +438,7 @@ namespace System.IO { using (sMonitor.Enter()) { - var ofn = (Windows.OpenFileName*)lparam; + var ofn = (Windows.OpenFileName*)(void*)lparam; sHookMap[(int)hWnd] = (CommonDialog)Internal.UnsafeCastToObject((void*)ofn.mCustData); } } diff --git a/BeefLibs/corlib/src/Object.bf b/BeefLibs/corlib/src/Object.bf index 6c302c04..8cf40d0c 100644 --- a/BeefLibs/corlib/src/Object.bf +++ b/BeefLibs/corlib/src/Object.bf @@ -45,7 +45,7 @@ namespace System { Type type; #if BF_ENABLE_OBJECT_DEBUG_FLAGS - ClassVData* maskedVData = (ClassVData*)(mClassVData & ~(int)0xFF); + ClassVData* maskedVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF); type = maskedVData.mType; #else type = mClassVData.mType; @@ -63,7 +63,7 @@ namespace System { Type type; #if BF_ENABLE_OBJECT_DEBUG_FLAGS - ClassVData* maskedVData = (ClassVData*)(mClassVData & ~(int)0xFF); + ClassVData* maskedVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF); type = maskedVData.mType; #else type = mClassVData.mType; diff --git a/BeefLibs/corlib/src/Pointer.bf b/BeefLibs/corlib/src/Pointer.bf index b799b376..f50a11f8 100644 --- a/BeefLibs/corlib/src/Pointer.bf +++ b/BeefLibs/corlib/src/Pointer.bf @@ -23,7 +23,7 @@ namespace System public int GetHashCode() { - return (int)mVal; + return (int)(void*)mVal; } } } diff --git a/BeefTools/BeefPerf/src/BPClient.bf b/BeefTools/BeefPerf/src/BPClient.bf index 9c12bc77..d94f42ab 100644 --- a/BeefTools/BeefPerf/src/BPClient.bf +++ b/BeefTools/BeefPerf/src/BPClient.bf @@ -1566,7 +1566,7 @@ namespace BeefPerf uint32 tickMSNow = (.)ReadSLEB128(); int64 clockRate = (.)ReadSLEB128(); - mTicksToUSScale = 1000.0 / clockRate; + mTicksToUSScale = 1000000.0 / clockRate; /*if (mFirstTimeStamp == -1) { diff --git a/BeefySysLib/platform/win/Platform.cpp b/BeefySysLib/platform/win/Platform.cpp index 531980bd..b2bd5ab7 100644 --- a/BeefySysLib/platform/win/Platform.cpp +++ b/BeefySysLib/platform/win/Platform.cpp @@ -909,8 +909,25 @@ static void __cdecl AbortHandler(int) 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) { + InitCPUFreq(); + ::_set_error_mode(_OUT_TO_STDERR); #ifdef _DEBUG @@ -1123,10 +1140,28 @@ BFP_EXPORT int64 BFP_CALLTYPE BfpSystem_GetCPUTick() } BFP_EXPORT int64 BFP_CALLTYPE BfpSystem_GetCPUTickFreq() -{ - LARGE_INTEGER freq = { 0 }; - QueryPerformanceFrequency(&freq); - return freq.QuadPart; +{ + LARGE_INTEGER largeVal = { 0 }; + QueryPerformanceFrequency(&largeVal); + 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) diff --git a/BeefySysLib/util/Array.h b/BeefySysLib/util/Array.h index 437e32fc..fd2bbd05 100644 --- a/BeefySysLib/util/Array.h +++ b/BeefySysLib/util/Array.h @@ -639,7 +639,7 @@ public: 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); if (this->mSize + size > this->mAllocSize) @@ -934,7 +934,7 @@ public: 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); if (this->mSize + size > this->mAllocSize) diff --git a/BeefySysLib/util/BeefPerf.cpp b/BeefySysLib/util/BeefPerf.cpp index 202c22ef..f0f24075 100644 --- a/BeefySysLib/util/BeefPerf.cpp +++ b/BeefySysLib/util/BeefPerf.cpp @@ -355,7 +355,7 @@ static int64 GetTimestamp() #ifdef BF_PLATFORM_WINDOWS return __rdtsc() / 100; #else - return BfpSystem_GetCPUTick(); + return BfpSystem_GetCPUTick() / 100; #endif } diff --git a/BeefySysLib/util/BumpAllocator.h b/BeefySysLib/util/BumpAllocator.h index 29eaa6f3..54c20f61 100644 --- a/BeefySysLib/util/BumpAllocator.h +++ b/BeefySysLib/util/BumpAllocator.h @@ -186,7 +186,7 @@ public: 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)); @@ -194,7 +194,7 @@ public: return retVal; } - uint8* AllocBytes(int wantSize, const char* dbgName = "AllocBytes") + uint8* AllocBytes(intptr wantSize, const char* dbgName = "AllocBytes") { #ifdef BUMPALLOC_TRACKALLOCS BumpAllocTrackedEntry* allocSizePtr; @@ -237,6 +237,11 @@ class AllocatorBump public: BumpAllocator* mAlloc; + AllocatorBump() + { + mAlloc = NULL; + } + T* allocate(intptr count) { return (T*)mAlloc->AllocBytes((int)(sizeof(T) * count), alignof(T)); @@ -245,6 +250,16 @@ public: void deallocate(T* ptr) { } + + void* rawAllocate(intptr size) + { + return mAlloc->AllocBytes(size, 16); + } + + void rawDeallocate(void* ptr) + { + + } }; diff --git a/BeefySysLib/util/ChunkedDataBuffer.cpp b/BeefySysLib/util/ChunkedDataBuffer.cpp index 6a7e9b90..ecd308cc 100644 --- a/BeefySysLib/util/ChunkedDataBuffer.cpp +++ b/BeefySysLib/util/ChunkedDataBuffer.cpp @@ -107,6 +107,42 @@ void ChunkedDataBuffer::Write(uint8 byte) 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() { return mReadPoolIdx * ALLOC_SIZE + (int)(mReadCurPtr - mReadCurAlloc); diff --git a/BeefySysLib/util/ChunkedDataBuffer.h b/BeefySysLib/util/ChunkedDataBuffer.h index 8d106266..13b90a8e 100644 --- a/BeefySysLib/util/ChunkedDataBuffer.h +++ b/BeefySysLib/util/ChunkedDataBuffer.h @@ -32,6 +32,9 @@ public: void GrowPool(); void Write(const void* data, int size); void Write(uint8 byte); + void Write_2(uint16 val); + void Write_3(uint32 val); + void Write_4(uint32 val); int GetReadPos(); void SetReadPos(int pos); void NextReadPool(); diff --git a/BeefySysLib/util/HashSet.h b/BeefySysLib/util/HashSet.h index 8094f18b..36d11247 100644 --- a/BeefySysLib/util/HashSet.h +++ b/BeefySysLib/util/HashSet.h @@ -1,12 +1,12 @@ #pragma once -#include "../Common.h" +#include "Array.h" #include NS_BF_BEGIN; -template -class HashSet +template > +class HashSet : public TAlloc { public: typedef int int_cosize; @@ -254,14 +254,14 @@ private: Resize(ExpandSize(mCount), false); } - void Resize(int newSize, bool forceNewHashCodes) + void Resize(intptr newSize, bool forceNewHashCodes) { 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++) newBuckets[i] = -1; - Entry* newEntries = new Entry[newSize]; - //mEntries.CopyTo(newEntries, 0, 0, mCount); + Entry* newEntries = (Entry*)rawAllocate(sizeof(Entry)*newSize); + for (int i = 0; i < mCount; i++) { auto& newEntry = newEntries[i]; @@ -294,12 +294,12 @@ private: } } - delete[] mBuckets; - delete[] mEntries; + rawDeallocate(mBuckets); + rawDeallocate(mEntries); mBuckets = newBuckets; mEntries = newEntries; - mAllocSize = newSize; + mAllocSize = (int_cosize)newSize; } int FindEntry(const TKey& key) @@ -332,10 +332,10 @@ private: void Initialize(intptr capacity) { int_cosize size = GetPrimeish((int_cosize)capacity); - mBuckets = new int_cosize[size]; + mBuckets = (int_cosize*)rawAllocate(sizeof(int_cosize) * size); mAllocSize = size; 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; } @@ -431,8 +431,8 @@ public: } else { - mBuckets = new int_cosize[mAllocSize]; - mEntries = new Entry[mAllocSize]; + mBuckets = (int_cosize*)rawAllocate(sizeof(int_cosize) * mAllocSize); + mEntries = (Entry*)rawAllocate(sizeof(Entry) * mAllocSize); for (int_cosize i = 0; i < mAllocSize; i++) mBuckets[i] = val.mBuckets[i]; @@ -476,8 +476,8 @@ public: } } - delete[] mBuckets; - delete[] mEntries; + rawDeallocate(mBuckets); + rawDeallocate(mEntries); } HashSet& operator=(const HashSet& rhs) diff --git a/BeefySysLib/util/SizedArray.h b/BeefySysLib/util/SizedArray.h index 296078c9..95da8999 100644 --- a/BeefySysLib/util/SizedArray.h +++ b/BeefySysLib/util/SizedArray.h @@ -217,7 +217,7 @@ public: BF_ASSERT((uintptr)idx < (uintptr)this->mSize); return this->mVals[idx]; } - + bool operator==(const SizedArrayBase& arrB) const { if (this->mSize != arrB.mSize) @@ -288,6 +288,11 @@ public: this->mSize = 0; } + void Clear() + { + this->mSize = 0; + } + /*void Free() { if (this->mVals != NULL) @@ -1060,17 +1065,27 @@ public: } }; +template +static bool operator==(const ArrayBase& arrA, const SizedArrayBase& 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; -/*namespace std +namespace std { template - struct hash > + struct hash > { - size_t operator()(const Beefy::Array& val) const + size_t operator()(const Beefy::SizedArrayImpl& val) const { - return _Hash_seq((const uint8*)val.mVals, sizeof(T) * val.mSize); + return HashBytes((const uint8*)val.mVals, sizeof(T) * val.mSize); } }; -}*/ - +} diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index c6910bc9..f14328e9 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -993,6 +993,8 @@ bool BfMethodMatcher::WantsCheckMethod(BfProtectionCheckFlags& flags, BfTypeInst bool BfMethodMatcher::CheckMethod(BfTypeInstance* typeInstance, BfMethodDef* checkMethod, bool isFailurePass) { + BP_ZONE("BfMethodMatcher::CheckMethod"); + bool hadMatch = false; // Never consider overrides - they only get found at original method declaration @@ -2905,7 +2907,9 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfIdentifierNode* identifierNode, 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) @@ -3148,7 +3152,7 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar if (resolvedFieldType->IsValuelessType()) { - return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), resolvedFieldType, true); + return BfTypedValue(BfIRValue::sValueless, resolvedFieldType, true); } if (isConst) @@ -7285,8 +7289,7 @@ void BfExprEvaluator::LookupQualifiedName(BfAstNode* nameNode, BfIdentifierNode* void BfExprEvaluator::LookupQualifiedStaticField(BfQualifiedNameNode* nameNode, bool ignoreIdentifierNotFoundError) { // Lookup left side as a type - { - SetAndRestoreValue prevHadIgnoreError(mModule->mHadIgnoredError, false); + { BfType* type = NULL; { type = mModule->ResolveTypeRef(nameNode->mLeft, NULL, BfPopulateType_Data, BfResolveTypeRefFlag_AllowRef); @@ -7371,8 +7374,7 @@ void BfExprEvaluator::LookupQualifiedStaticField(BfQualifiedNameNode* nameNode, void BfExprEvaluator::LookupQualifiedStaticField(BfAstNode* nameNode, BfIdentifierNode* nameLeft, BfIdentifierNode* nameRight, bool ignoreIdentifierNotFoundError) { // Lookup left side as a type - { - SetAndRestoreValue prevHadIgnoreError(mModule->mHadIgnoredError, false); + { BfType* type = NULL; { SetAndRestoreValue prevIgnoreErrors(mModule->mIgnoreErrors, true); @@ -8349,6 +8351,7 @@ bool BfExprEvaluator::CanBindDelegate(BfDelegateBindExpression* delegateBindExpr for (int i = 0; i < (int) methodInstance->GetParamCount(); i++) { auto typedValueExpr = &typedValueExprs[i]; + typedValueExpr->mTypedValue.mValue = BfIRValue(BfIRValueFlags_Value, -1); typedValueExpr->mTypedValue.mType = methodInstance->GetParamType(i); typedValueExpr->mRefNode = NULL; args[i] = typedValueExpr; @@ -8734,6 +8737,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr) for (int i = 0; i < (int)methodInstance->GetParamCount(); i++) { auto typedValueExpr = &typedValueExprs[i]; + typedValueExpr->mTypedValue.mValue = BfIRValue(BfIRValueFlags_Value, -1); typedValueExpr->mTypedValue.mType = methodInstance->GetParamType(i); typedValueExpr->mRefNode = NULL; args[i] = typedValueExpr; @@ -13160,13 +13164,13 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m if (mayBeSkipCall) resolveArgsFlags = (BfResolveArgFlags)(resolveArgsFlags | BfResolveArgFlag_DeferParamValues); -// static int sCallIdx = 0; -// sCallIdx++; -// int callIdx = sCallIdx; -// if (callIdx == 1557) -// { -// NOP; -// } + static int sCallIdx = 0; + sCallIdx++; + int callIdx = sCallIdx; + if (callIdx == 1557) + { + NOP; + } BfCheckedKind checkedKind = BfCheckedKind_NotSet; if (attributeState.mCustomAttributes != NULL) @@ -17208,8 +17212,8 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod BfPointerType* resultPointerType = (BfPointerType*)resultType; BfType* intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr); - convLeftValue = mModule->CastToValue(leftExpression, leftValue, intPtrType, BfCastFlags_Explicit); - convRightValue = mModule->CastToValue(rightExpression, rightValue, intPtrType, BfCastFlags_Explicit); + convLeftValue = mModule->CastToValue(leftExpression, leftValue, intPtrType, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromCompiler)); + convRightValue = mModule->CastToValue(rightExpression, rightValue, intPtrType, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromCompiler)); BfIRValue diffValue = mModule->mBfIRBuilder->CreateSub(convLeftValue, convRightValue); diffValue = mModule->mBfIRBuilder->CreateDiv(diffValue, mModule->GetConstValue(resultPointerType->mElementType->mSize, intPtrType), true); mResult = BfTypedValue(diffValue, intPtrType); diff --git a/IDEHelper/Compiler/BfIRBuilder.cpp b/IDEHelper/Compiler/BfIRBuilder.cpp index ca563b34..b3a302f9 100644 --- a/IDEHelper/Compiler/BfIRBuilder.cpp +++ b/IDEHelper/Compiler/BfIRBuilder.cpp @@ -215,6 +215,8 @@ static llvm::GlobalValue::LinkageTypes LLVMMapLinkageType(BfIRLinkageType linkag return llvmLinkageType; } +BfIRValue BfIRValue::sValueless(BfIRValueFlags_Value, -1); + bool BfIRValue::IsFake() const { return mId < -1; @@ -1452,6 +1454,98 @@ void BfIRBuilder::WriteSLEB128(int64 value) 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) { 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 retVal = WriteCmd(BfIRCmd_DbgCreateBasicType, name, sizeInBits, alignInBits, encoding); + BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateBasicType, name, (int32)sizeInBits, (int32)alignInBits, encoding); NEW_CMD_INSERTED_IRMD; return retVal; } BfIRMDNode BfIRBuilder::DbgCreateStructType(BfIRMDNode context, const StringImpl& name, BfIRMDNode file, int lineNum, int64 sizeInBits, int64 alignInBits, int flags, BfIRMDNode derivedFrom, const BfSizedArray& 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; return retVal; } BfIRMDNode BfIRBuilder::DbgCreateEnumerationType(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNumber, int64 sizeInBits, int64 alignInBits, const BfSizedArray& 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; 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 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; 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 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; 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 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; 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 retVal = WriteCmd(BfIRCmd_DbgCreateInheritance, type, baseType, baseOffset, flags); + BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateInheritance, type, baseType, (int32)baseOffset, flags); NEW_CMD_INSERTED_IRMD; return retVal; } diff --git a/IDEHelper/Compiler/BfIRBuilder.h b/IDEHelper/Compiler/BfIRBuilder.h index 3e6604f1..03ed8612 100644 --- a/IDEHelper/Compiler/BfIRBuilder.h +++ b/IDEHelper/Compiler/BfIRBuilder.h @@ -473,6 +473,7 @@ public: public: int mId; BfIRValueFlags mFlags; + static BfIRValue sValueless; #ifdef CHECK_CONSTHOLDER BfIRConstHolder* mHolder; @@ -883,7 +884,8 @@ public: public: ~BfIRBuilder(); - void WriteSLEB128(int64 val); + void WriteSLEB128(int64 val); + void WriteSLEB128(int32 val); void Write(uint8 val); void Write(bool val); void Write(int val); diff --git a/IDEHelper/Compiler/BfMangler.cpp b/IDEHelper/Compiler/BfMangler.cpp index e79dac33..cdfb3272 100644 --- a/IDEHelper/Compiler/BfMangler.cpp +++ b/IDEHelper/Compiler/BfMangler.cpp @@ -304,7 +304,7 @@ void BfGNUMangler::MangleTypeInst(MangleContext& mangleContext, StringImpl& name name += "N8delegateI"; else name += "N8functionI"; - BfTypeVector typeVec; + SizedArray typeVec; typeVec.push_back(invokeMethodInst->mReturnType); 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; name += "?$__TUPLE"; - BfTypeVector typeVec; + SizedArray typeVec; for (auto& fieldInst : tupleType->mFieldInstances) { BfFieldDef* fieldDef = fieldInst.GetFieldDef(); @@ -1120,7 +1120,7 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name += "?$delegate"; else name += "?$function"; - BfTypeVector typeVec; + SizedArray typeVec; typeVec.push_back(BfNodeDynCast(methodDef->mReturnTypeRef)->mType); for (int paramIdx = 0; paramIdx < (int)methodDef->mParams.size(); paramIdx++) { @@ -1139,7 +1139,7 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& // name += "?$delegate"; // else // name += "?$function"; -// BfTypeVector typeVec; +// SizedArray typeVec; // typeVec.push_back(invokeMethodInst->mReturnType); // 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; name += "?$Box@"; - BfTypeVector typeVec; + SizedArray typeVec; typeVec.push_back(boxedType->GetModifiedElementType()); AddGenericArgs(mangleContext, name, typeVec); name += '@'; diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 0f166d3c..8ab5af5e 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -803,8 +803,7 @@ BfModule::BfModule(BfContext* context, const StringImpl& moduleName) mHadBuildError = false; mHadBuildWarning = false; mIgnoreErrors = false; - mIgnoreWarnings = false; - mHadIgnoredError = false; + mIgnoreWarnings = false; mReportErrors = true; mIsInsideAutoComplete = 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 if (type->mSize == 0) - return BfTypedValue(BfIRValue(), type); + return BfTypedValue(BfIRValue::sValueless, type); else return BfTypedValue(mBfIRBuilder->GetFakeVal(), type); } @@ -2446,8 +2445,7 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers BP_ZONE("BfModule::Fail"); if (mIgnoreErrors) - { - mHadIgnoredError = true; + { return NULL; } @@ -8320,6 +8318,9 @@ void BfModule::EmitDynamicCastCheck(const BfTypedValue& targetValue, BfType* tar void BfModule::EmitDynamicCastCheck(BfTypedValue typedVal, BfType* type, bool allowNull) { + if (mBfIRBuilder->mIgnoreWrites) + return; + bool emitDynamicCastCheck = mCompiler->mOptions.mEmitDynamicCastCheck; auto typeOptions = GetTypeOptions(); if (typeOptions != NULL) @@ -8355,19 +8356,34 @@ void BfModule::EmitDynamicCastCheck(BfTypedValue typedVal, BfType* type, bool al 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"); BfTypeInstance* fromStructTypeInstance = typedVal.mType->ToTypeInstance(); if (typedVal.mType->IsNullable()) - { + { typedVal = MakeAddressable(typedVal); auto innerType = typedVal.mType->GetUnderlyingType(); if (!innerType->IsValueType()) { - Fail("Only value types can be boxed", srcNode); + if (!mIgnoreErrors) + Fail("Only value types can be boxed", srcNode); 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 boxBB = mBfIRBuilder->CreateBlock("boxedN.notNull"); @@ -8378,13 +8394,9 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp auto hasValue = mBfIRBuilder->CreateLoad(hasValueAddr); mBfIRBuilder->CreateCondBr(hasValue, boxBB, endBB); - - auto boxedType = CreateBoxedType(innerType); + AddDependency(boxedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields); - auto resultType = toType; - if (resultType == NULL) - resultType = boxedType; - + mBfIRBuilder->AddBlock(boxBB); mBfIRBuilder->SetInsertPoint(boxBB); BfScopeData newScope; @@ -8443,17 +8455,16 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp if (fromStructTypeInstance == NULL) return BfTypedValue(); - // Need to box it - auto boxedType = CreateBoxedType(typedVal.mType); - bool isBoxedType = (fromStructTypeInstance != NULL) && (toType->IsBoxed()) && (boxedType == toType); - + // Need to box it + bool isBoxedType = (fromStructTypeInstance != NULL) && (toType->IsBoxed()); + if ((toType == NULL) || (toType == mContext->mBfObjectType) || (isBoxedType) || (alreadyCheckedCast) || (TypeIsSubTypeOf(fromStructTypeInstance, toTypeInstance))) - { - if (typedVal.mType->IsPointer()) - { - NOP; - } - + { + if (mBfIRBuilder->mIgnoreWrites) + return BfTypedValue(mBfIRBuilder->GetFakeVal(), (toType != NULL) ? toType : CreateBoxedType(typedVal.mType)); + + auto boxedType = CreateBoxedType(typedVal.mType); + mBfIRBuilder->PopulateType(boxedType); AddDependency(boxedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields); auto allocaInst = AllocFromType(boxedType, allocTarget, BfIRValue(), BfIRValue(), 0, callDtor ? BfAllocFlags_None : BfAllocFlags_NoDtorCall); @@ -8463,7 +8474,7 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp if (boxedType->IsUnspecializedType()) { - BF_ASSERT(mCurMethodInstance->mIsUnspecialized); + BF_ASSERT((srcNode == NULL) || (mCurMethodInstance->mIsUnspecialized)); } else { @@ -8656,7 +8667,7 @@ int BfModule::GetGenericParamAndReturnCount(BfMethodInstance* methodInstance) return genericCount; } -BfModule* BfModule::GetSpecializedMethodModule(const Array& projectList) +BfModule* BfModule::GetSpecializedMethodModule(const SizedArrayImpl& projectList) { BF_ASSERT(!mIsScratchModule); BF_ASSERT(mIsReified); @@ -8667,7 +8678,7 @@ BfModule* BfModule::GetSpecializedMethodModule(const Array& projectL BfModule* specModule = NULL; BfModule** specModulePtr = NULL; - if (mainModule->mSpecializedMethodModules.TryGetValue(projectList, &specModulePtr)) + if (mainModule->mSpecializedMethodModules.TryGetValueWith(projectList, &specModulePtr)) { return *specModulePtr; } @@ -8681,7 +8692,11 @@ BfModule* BfModule::GetSpecializedMethodModule(const Array& projectL specModule->mParentModule = mainModule; specModule->mIsSpecializedMethodModuleRoot = true; specModule->Init(); - mainModule->mSpecializedMethodModules[projectList] = specModule; + + Array projList; + for (auto project : projectList) + projList.Add(project); + mainModule->mSpecializedMethodModules[projList] = specModule; } return specModule; } @@ -11080,7 +11095,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM } BfTypeVector sanitizedMethodGenericArguments; - Array projectList; + SizedArray projectList; bool isUnspecializedPass = (flags & BfGetMethodInstanceFlag_UnspecializedPass) != 0; if ((isUnspecializedPass) && (methodDef->mGenericParams.size() == 0)) @@ -19095,7 +19110,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool if ((paramDef != NULL) && (paramDef->mParamDeclaration != NULL) && (paramDef->mParamDeclaration->mInitializer != NULL) && (!paramDef->mParamDeclaration->mInitializer->IsA())) { - BfMethodState methodState; + BfMethodState methodState; SetAndRestoreValue prevMethodState(mCurMethodState, &methodState); methodState.mTempKind = BfMethodState::TempKind_Static; diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 479b9bca..734a5122 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -833,6 +833,7 @@ public: }; public: + BumpAllocator mBumpAlloc; BfMethodState* mPrevMethodState; // Only non-null for things like local methods BfConstResolveState* mConstResolveState; BfMethodInstance* mMethodInstance; @@ -841,8 +842,8 @@ public: BfIRBlock mIRHeadBlock; BfIRBlock mIRInitBlock; BfIRBlock mIREntryBlock; - Array mLocals; - HashSet mLocalVarSet; + Array > mLocals; + HashSet > mLocalVarSet; Array mLocalMethods; Dictionary mLocalMethodMap; Dictionary mLocalMethodCache; // So any lambda 'capturing' and 'processing' stages use the same local method @@ -899,7 +900,12 @@ public: public: BfMethodState() - { + { + mLocals.mAlloc = &mBumpAlloc; + mLocals.Reserve(8); + mLocalVarSet.mAlloc = &mBumpAlloc; + mLocalVarSet.Reserve(8); + mMethodInstance = NULL; mPrevMethodState = NULL; mConstResolveState = NULL; @@ -1343,8 +1349,7 @@ public: bool mHadBuildWarning; bool mIgnoreErrors; bool mIgnoreWarnings; - bool mSetIllegalSrcPosition; - bool mHadIgnoredError; + bool mSetIllegalSrcPosition; bool mReportErrors; // Still puts system in error state when set to false bool mIsInsideAutoComplete; bool mIsHotModule; @@ -1439,6 +1444,7 @@ public: BfDeferredCallEntry* AddDeferredCall(const BfModuleMethodInstance& moduleMethodInstance, SizedArrayImpl& llvmArgs, BfScopeData* scope, BfAstNode* srcNode = NULL, bool bypassVirtual = false, bool doNullCheck = false); void EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry); void EmitDeferredCallProcessor(SLIList& callEntries, BfIRValue callTail); + bool DoCanImplicitlyCast(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); 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* GetUnspecializedMethodInstance(BfMethodInstance* methodInstance); // Unspecialized owner type and unspecialized method type int GetGenericParamAndReturnCount(BfMethodInstance* methodInstance); - BfModule* GetSpecializedMethodModule(const Array& projectList); + BfModule* GetSpecializedMethodModule(const SizedArrayImpl& projectList); 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, const Array& paramTypes, bool checkBase = false); diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 8daa9172..584caced 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -4653,8 +4653,6 @@ BfBoxedType* BfModule::CreateBoxedType(BfType* resolvedTypeRef) { bool isStructPtr = false; -// if (resolvedTypeRef->IsPointer()) -// resolvedTypeRef = ((BfPointerType*)resolvedTypeRef)->mElementType; if (resolvedTypeRef->IsPrimitiveType()) { auto primType = (BfPrimitiveType*)resolvedTypeRef; @@ -7696,14 +7694,13 @@ BfType* BfModule::ResolveTypeRef(BfAstNode* astNode, const BfSizedArraymGenericParamFlags & (BfGenericParamFlag_Class | BfGenericParamFlag_StructPtr)) || ((genericParamInst->mTypeConstraint != NULL) && - ((genericParamInst->mTypeConstraint->IsPointer()) || (genericParamInst->mTypeConstraint->IsObjectOrInterface())))) + ((genericParamInst->mTypeConstraint->IsPointer()) || (genericParamInst->mTypeConstraint->IsObjectOrInterface())))) { return true; } @@ -7868,8 +7865,8 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl // And from T* to T[size]* explicitly if (fromUnderlying->IsSizedArray()) fromUnderlying = fromUnderlying->GetUnderlyingType(); -// if ((toUnderlying->IsSizedArray()) && (explicitCast)) -// toUnderlying = toUnderlying->GetUnderlyingType(); + // if ((toUnderlying->IsSizedArray()) && (explicitCast)) + // toUnderlying = toUnderlying->GetUnderlyingType(); if ((fromUnderlying == toUnderlying) || (TypeIsSubTypeOf(fromUnderlying->ToTypeInstance(), toUnderlying->ToTypeInstance())) || @@ -7905,20 +7902,20 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl if (((fromType->IsValueType()) || (fromType->IsPointer()) || (fromType->IsValuelessType())) && ((toType->IsInterface()) || (toType == mContext->mBfObjectType))) { -// if (fromType->IsPointer()) -// { -// if (toType == mContext->mBfObjectType) -// return true; -// return false; -// } - + // if (fromType->IsPointer()) + // { + // if (toType == mContext->mBfObjectType) + // return true; + // return false; + // } + if (toType == mContext->mBfObjectType) return true; - BfTypeInstance* fromStructTypeInstance = NULL; - fromStructTypeInstance = fromType->ToTypeInstance(); - if (fromStructTypeInstance == NULL) - { + BfTypeInstance* fromStructTypeInstance = NULL; + fromStructTypeInstance = fromType->ToTypeInstance(); + if (fromStructTypeInstance == NULL) + { if (fromType->IsPrimitiveType()) { auto primType = (BfPrimitiveType*)fromType; @@ -7926,15 +7923,79 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl } else return false; - } + } - auto toTypeInstance = toType->ToTypeInstance(); - // Need to box it - if (TypeIsSubTypeOf(fromStructTypeInstance, toTypeInstance)) - return true; + auto toTypeInstance = toType->ToTypeInstance(); + // Need to box it + if (TypeIsSubTypeOf(fromStructTypeInstance, toTypeInstance)) + return true; } - if (fromType->IsRef()) + // Null -> Nullable + if ((typedVal.mType->IsNull()) && (toType->IsNullable())) + { + return true; + } + + // Nullable -> Nullable + 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()) { @@ -7946,7 +8007,7 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl // ref T -> T return fromType->GetUnderlyingType() == toType; } - } + }*/ // Int -> Enum if ((typedVal.mType->IsIntegral()) && (toType->IsEnum())) @@ -8005,7 +8066,7 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl if (constant != NULL) { BfConstExprValueType* toConstExprValueType = (BfConstExprValueType*)toType; - + auto variantVal = TypedValueToVariant(NULL, typedVal); if ((mBfIRBuilder->IsInt(variantVal.mTypeCode)) && (mBfIRBuilder->IsInt(toConstExprValueType->mValue.mTypeCode))) { @@ -8054,15 +8115,15 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl } else if (toType->IsSigned()) { - if (toType->mSize == 8) // int64 - return true; - else - { - int64 minVal = -(1LL << (8 * toType->mSize - 1)); - int64 maxVal = (1LL << (8 * toType->mSize - 1)) - 1; - if ((srcVal >= minVal) && (srcVal <= maxVal)) - return true; - } + if (toType->mSize == 8) // int64 + return true; + else + { + int64 minVal = -(1LL << (8 * toType->mSize - 1)); + int64 maxVal = (1LL << (8 * toType->mSize - 1)) - 1; + if ((srcVal >= minVal) && (srcVal <= maxVal)) + return true; + } } else if (toType->mSize == 8) // ulong { @@ -8420,7 +8481,7 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl } BfBaseClassWalker baseClassWalker(fromType, toType, this); - + while (true) { auto entry = baseClassWalker.Next(); @@ -8455,7 +8516,7 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl // Selection pass if (pass < 2) { - auto methodCheckFromType = methodFromType; + auto methodCheckFromType = methodFromType; auto methodCheckToType = methodToType; if (pass == 1) { @@ -8495,13 +8556,13 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl bestToDist = toDist; bestToType = methodToType; } - } + } } else if (pass == 2) // Execution Pass { if ((methodFromType == bestFromType) && (methodToType == bestToType)) { - return true; + return CanImplicitlyCast(BfTypedValue(BfIRValue::sValueless, bestToType), toType, castFlags); } } } @@ -8515,12 +8576,59 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl bestFromType = bestNegFromType; if (bestToType == NULL) bestToType = bestNegToType; - } + } + } + + // 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; } +// 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 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) { 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) { bool explicitCast = (castFlags & BfCastFlags_Explicit) != 0; + bool ignoreErrors = mIgnoreErrors || ((castFlags & BfCastFlags_SilentFail) != 0); + bool ignoreWrites = mBfIRBuilder->mIgnoreWrites; if (typedVal.mType == toType) { @@ -8692,12 +8802,11 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp // void* -> intptr if ((typedVal.mType->IsPointer()) && (toType->IsIntPtr())) - { - //TODO: Put back - /*if ((!typedVal.mType->GetUnderlyingType()->IsVoid()) && ((castFlags & BfCastFlags_FromCompiler) == 0)) + { + if ((!ignoreErrors) && (!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); - }*/ + } auto toPrimitive = (BfPrimitiveType*)toType; return mBfIRBuilder->CreatePtrToInt(typedVal.mValue, toPrimitive->mTypeDef->mTypeCode); @@ -8705,12 +8814,11 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp // intptr -> void* if ((typedVal.mType->IsIntPtr()) && (toType->IsPointer())) - { - //TODO: Put back - /*if ((!toType->GetUnderlyingType()->IsVoid()) && ((castFlags & BfCastFlags_FromCompiler) == 0)) + { + if ((!ignoreErrors) && (!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); - }*/ + } return mBfIRBuilder->CreateIntToPtr(typedVal.mValue, mBfIRBuilder->MapType(toType)); } @@ -8846,30 +8954,49 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp } } - // ObjectInst|IFace -> object|IFace - if ((typedVal.mType->IsObject() || (typedVal.mType->IsInterface())) && ((toType->IsObject() || (toType->IsInterface())))) + if ((typedVal.mType->IsTypeInstance()) && (toType->IsTypeInstance())) { - bool allowCast = false; - auto fromTypeInstance = typedVal.mType->ToTypeInstance(); auto toTypeInstance = toType->ToTypeInstance(); - if (TypeIsSubTypeOf(fromTypeInstance, toTypeInstance)) - allowCast = true; - else if ((explicitCast) && - ((toType->IsInterface()) || (TypeIsSubTypeOf(toTypeInstance, fromTypeInstance)))) + if ((typedVal.mType->IsValueType()) && (toType->IsValueType())) { - if (toType->IsObjectOrInterface()) + bool allowCast = false; + if (TypeIsSubTypeOf(fromTypeInstance, toTypeInstance)) + allowCast = true; + if (allowCast) { - if ((castFlags & BfCastFlags_Unchecked) == 0) - EmitDynamicCastCheck(typedVal, toType, true); + if (toType->IsValuelessType()) + return BfIRValue::sValueless; } - allowCast = true; } - if (allowCast) - return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType)); - } + // ObjectInst|IFace -> object|IFace + 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 if ((typedVal.mType->IsMethodRef()) && (toType->IsFunction())) @@ -8918,7 +9045,11 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp allowCast = true; if (allowCast) + { + if (ignoreWrites) + return mBfIRBuilder->GetFakeVal(); return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType)); + } } else if (typedVal.mType->IsObject()) { @@ -8951,9 +9082,10 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp ((toType->IsValueType()) || (toType->IsPointer()))) { if (toType->IsValuelessType()) - { - return mBfIRBuilder->GetFakeVal(); - } + return BfIRValue::sValueless; + + if (ignoreWrites) + return mBfIRBuilder->GetFakeVal(); // Unbox! if ((castFlags & BfCastFlags_Unchecked) == 0) @@ -9036,6 +9168,9 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp // Null -> Nullable if ((typedVal.mType->IsNull()) && (toType->IsNullable())) { + if (ignoreWrites) + return mBfIRBuilder->GetFakeVal(); + if ((castFlags & BfCastFlags_PreferAddr) != 0) { auto boolType = GetPrimitiveType(BfTypeCode_Boolean); @@ -9059,6 +9194,9 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp // Nullable -> Nullable if ((typedVal.mType->IsNullable()) && (toType->IsNullable())) { + if (ignoreWrites) + return mBfIRBuilder->GetFakeVal(); + auto fromNullableType = (BfGenericTypeInstance*)typedVal.mType; 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 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) return BfIRValue(); @@ -9166,7 +9304,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp return typedVal.mValue; } - if ((castFlags & BfCastFlags_SilentFail) == 0) + if (!ignoreErrors) { String valStr; VariantToString(valStr, variantVal); @@ -9533,7 +9671,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp if (fromDist < 0) { // 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; } @@ -9623,7 +9761,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp { 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()); } @@ -9653,7 +9791,10 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp auto castedFromValue = Cast(srcNode, typedVal, bestFromType, castFlags); if (!castedFromValue) return BfIRValue(); - + + if (ignoreWrites) + return mBfIRBuilder->GetFakeVal(); + SizedArray args; exprEvaluator.PushArg(castedFromValue, 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)); if (isAmbiguousCast) { - 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); + if (!ignoreErrors) + { + 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(); } @@ -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 auto opToVal = genericParam->mExternType; - if (CanImplicitlyCast(opToVal, toType)) + if (CanImplicitlyCast(BfTypedValue(BfIRValue::sValueless, opToVal), toType)) 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 auto opToVal = genericParam->mExternType; - if (CanImplicitlyCast(opToVal, toType)) + if (CanImplicitlyCast(BfTypedValue(BfIRValue::sValueless, opToVal), toType)) return mBfIRBuilder->GetFakeVal(); } } @@ -9777,7 +9921,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp bool allowCast = explicitCast; if (toType == mCurTypeInstance) allowCast = true; - if ((!allowCast) && (typedVal.mType->IsIntegral()) && (!toType->IsEnum())) + if ((!allowCast) && (typedVal.mType->IsIntegral()) /*&& (!toType->IsEnum())*/) { // Allow implicit cast of zero 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); } + SetAndRestoreValue ignoreWrites(mBfIRBuilder->mIgnoreWrites, ignoreWrites); auto value = BoxValue(srcNode, typedVal, toType, scopeData, (castFlags & BfCastFlags_NoBoxDtor) == 0); if (value) return value.mValue; } - if ((castFlags & BfCastFlags_SilentFail) == 0) + if (!ignoreErrors) { - if (mIgnoreErrors) - return BfIRValue(); - const char* errStrF = explicitCast ? "Unable to 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; - auto checkTypeInst = typeInstance; - auto checkTypeDef = typeInstance->mTypeDef; - - auto checkCurTypeInst = mCurTypeInstance; // Only used for ReduceName - BfTypeDef* checkCurTypeDef = NULL; - if (checkCurTypeInst != NULL) - checkCurTypeDef = checkCurTypeInst->mTypeDef; - - std::function _AddTypeName = [&](BfTypeDef* checkTypeDef, int depth) + //auto checkTypeInst = typeInstance; + //auto checkTypeDef = typeInstance->mTypeDef; + + bool omitNamespace = (typeNameFlags & BfTypeNameFlag_OmitNamespace) != 0; + if ((typeNameFlags & BfTypeNameFlag_ReduceName) != 0) { - if (depth > 0) + for (auto& checkNamespace : mCurTypeInstance->mTypeDef->mNamespaceSearch) { - if ((typeNameFlags & BfTypeNameFlag_OmitOuterType) != 0) - return; + if (checkNamespace == typeInstance->mTypeDef->mNamespace) + 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 _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 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); - if (outerTypeInst == NULL) - return; - checkTypeInst = outerTypeInst; + checkCurTypeInst = GetOuterType(checkCurTypeInst); + checkCurTypeDef = checkCurTypeInst->mTypeDef; + } - while (checkCurTypeDef->mNestDepth > checkTypeDef->mNestDepth) + while (checkTypeDef != NULL) + { + if (TypeIsSubTypeOf(checkCurTypeInst, checkTypeInst)) { - checkCurTypeInst = GetOuterType(checkCurTypeInst); - checkCurTypeDef = checkCurTypeInst->mTypeDef; + endTypeDef = checkTypeDef; + break; } - if (TypeIsSubTypeOf(checkCurTypeInst, checkTypeInst)) - return; // Found outer type + checkCurTypeInst = GetOuterType(checkCurTypeInst); + if (checkCurTypeInst == NULL) + break; + checkCurTypeDef = checkCurTypeInst->mTypeDef; + + checkTypeInst = GetOuterType(checkTypeInst); + if (checkTypeInst == NULL) + break; + checkTypeDef = checkTypeInst->mTypeDef; } } + } - auto parentTypeDef = checkTypeDef->mOuterType; - if (parentTypeDef != NULL) - { - _AddTypeName(parentTypeDef, depth + 1); - } + BfTypeDef* checkTypeDef = typeInstance->mTypeDef; + while (checkTypeDef != NULL) + { + 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()) { @@ -10630,32 +10884,12 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF } str += '>'; } - } + } if (depth > 0) 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; } else if (resolvedType->IsPrimitiveType()) diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index 8747b690..3a02432b 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -3627,64 +3627,6 @@ String BfTypeUtils::HashEncode64(uint64 val) return outStr; } -void BfTypeUtils::GetProjectList(BfType* checkType, Array* 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) { return module->GetPrimitiveType(typeCode); diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.h b/IDEHelper/Compiler/BfResolvedTypeUtils.h index 3aa3128d..f5b99ca5 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.h +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.h @@ -2332,7 +2332,64 @@ public: static bool TypeToString(StringImpl& str, BfTypeDef* typeDef, BfTypeNameFlags typeNameFlags = BfTypeNameFlags_None); static bool TypeEquals(BfType* typeA, BfType* typeB, BfType* selfType); - static void GetProjectList(BfType* checkType, Array* projectVector, int immutableLength); + template + 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 void PopulateType(BfModule* module, BfType* type); diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index 8693109e..44bbdcb8 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -1162,7 +1162,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD BfLocalVariable* localDef = new BfLocalVariable(); if (varDecl->mNameNode != NULL) { - localDef->mName = varDecl->mNameNode->ToString(); + varDecl->mNameNode->ToString(localDef->mName); localDef->mNameNode = BfNodeDynCast(varDecl->mNameNode); } else @@ -1773,7 +1773,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD BfLocalVariable* localDef = new BfLocalVariable(); if (varDecl->mNameNode != NULL) - localDef->mName = varDecl->mNameNode->ToString(); + varDecl->mNameNode->ToString(localDef->mName); localDef->mNameNode = BfNodeDynCast(varDecl->mNameNode); localDef->mResolvedType = type; localDef->mIsAssigned = true; @@ -1906,7 +1906,7 @@ void BfModule::HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl, Bf bool initHandled = false; BfLocalVariable* localDef = new BfLocalVariable(); - localDef->mName = varNameNode->ToString(); + varNameNode->ToString(localDef->mName); localDef->mNameNode = BfNodeDynCast(varNameNode); localDef->mResolvedType = resolvedType; 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(); PopulateType(enumType); - String enumCaseName; + StringT<128> enumCaseName; if (nameNode != NULL) - enumCaseName = nameNode->ToString(); + nameNode->ToString(enumCaseName); auto tagType = GetPrimitiveType(BfTypeCode_Int32); if (enumVal.mType != enumType) diff --git a/IDEHelper/IDEHelper.vcxproj b/IDEHelper/IDEHelper.vcxproj index bf5f4eb4..7b7740c9 100644 --- a/IDEHelper/IDEHelper.vcxproj +++ b/IDEHelper/IDEHelper.vcxproj @@ -1,4 +1,4 @@ - + @@ -218,7 +218,7 @@ MaxSpeed true true - WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) + BP_DISABLED;WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions) ../;../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 MultiThreaded false