1
0
Fork 0
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:
Brian Fiete 2019-11-19 09:58:35 -08:00
parent 39fd8d2624
commit 098ad1ce55
25 changed files with 759 additions and 301 deletions

View file

@ -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<T>.sDataMask);
mRootEnumerator = (Enumerator*)(void*)(mEvent.mData & Event<T>.sDataMask);
}
mIdx = -1;
}

View file

@ -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:

View file

@ -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);
}
}

View file

@ -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;

View file

@ -23,7 +23,7 @@ namespace System
public int GetHashCode()
{
return (int)mVal;
return (int)(void*)mVal;
}
}
}

View file

@ -1566,7 +1566,7 @@ namespace BeefPerf
uint32 tickMSNow = (.)ReadSLEB128();
int64 clockRate = (.)ReadSLEB128();
mTicksToUSScale = 1000.0 / clockRate;
mTicksToUSScale = 1000000.0 / clockRate;
/*if (mFirstTimeStamp == -1)
{

View file

@ -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
@ -1124,9 +1141,27 @@ 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)

View file

@ -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)

View file

@ -355,7 +355,7 @@ static int64 GetTimestamp()
#ifdef BF_PLATFORM_WINDOWS
return __rdtsc() / 100;
#else
return BfpSystem_GetCPUTick();
return BfpSystem_GetCPUTick() / 100;
#endif
}

View file

@ -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)
{
}
};

View file

@ -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);

View file

@ -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();

View file

@ -1,12 +1,12 @@
#pragma once
#include "../Common.h"
#include "Array.h"
#include <unordered_map>
NS_BF_BEGIN;
template <typename TKey>
class HashSet
template <typename TKey, typename TAlloc = AllocatorCLib<TKey> >
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)

View file

@ -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 <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;
/*namespace std
namespace std
{
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);
}
};
}*/
}

View file

@ -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)
@ -7286,7 +7290,6 @@ void BfExprEvaluator::LookupQualifiedStaticField(BfQualifiedNameNode* nameNode,
{
// Lookup left side as a type
{
SetAndRestoreValue<bool> prevHadIgnoreError(mModule->mHadIgnoredError, false);
BfType* type = NULL;
{
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
{
SetAndRestoreValue<bool> prevHadIgnoreError(mModule->mHadIgnoredError, false);
BfType* type = NULL;
{
SetAndRestoreValue<bool> 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);

View file

@ -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<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;
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 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;
}

View file

@ -473,6 +473,7 @@ public:
public:
int mId;
BfIRValueFlags mFlags;
static BfIRValue sValueless;
#ifdef CHECK_CONSTHOLDER
BfIRConstHolder* mHolder;
@ -884,6 +885,7 @@ public:
~BfIRBuilder();
void WriteSLEB128(int64 val);
void WriteSLEB128(int32 val);
void Write(uint8 val);
void Write(bool val);
void Write(int val);

View file

@ -304,7 +304,7 @@ void BfGNUMangler::MangleTypeInst(MangleContext& mangleContext, StringImpl& name
name += "N8delegateI";
else
name += "N8functionI";
BfTypeVector typeVec;
SizedArray<BfType*, 8> 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<BfType*, 8> 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<BfType*, 8> typeVec;
typeVec.push_back(BfNodeDynCast<BfDirectTypeReference>(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<BfType*, 8> 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<BfType*, 8> typeVec;
typeVec.push_back(boxedType->GetModifiedElementType());
AddGenericArgs(mangleContext, name, typeVec);
name += '@';

View file

@ -804,7 +804,6 @@ BfModule::BfModule(BfContext* context, const StringImpl& moduleName)
mHadBuildWarning = false;
mIgnoreErrors = false;
mIgnoreWarnings = false;
mHadIgnoredError = 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);
}
@ -2447,7 +2446,6 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers
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,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)
{
if (mBfIRBuilder->mIgnoreWrites)
{
if (toType == mContext->mBfObjectType)
return BfTypedValue(mBfIRBuilder->GetFakeVal(), toType);
}
BP_ZONE("BoxValue");
BfTypeInstance* fromStructTypeInstance = typedVal.mType->ToTypeInstance();
@ -8365,10 +8372,19 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
auto innerType = typedVal.mType->GetUnderlyingType();
if (!innerType->IsValueType())
{
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");
auto endBB = mBfIRBuilder->CreateBlock("boxedN.end");
@ -8379,11 +8395,7 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
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);
@ -8444,15 +8456,14 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
return BfTypedValue();
// Need to box it
auto boxedType = CreateBoxedType(typedVal.mType);
bool isBoxedType = (fromStructTypeInstance != NULL) && (toType->IsBoxed()) && (boxedType == toType);
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);
@ -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<BfProject*>& projectList)
BfModule* BfModule::GetSpecializedMethodModule(const SizedArrayImpl<BfProject*>& projectList)
{
BF_ASSERT(!mIsScratchModule);
BF_ASSERT(mIsReified);
@ -8667,7 +8678,7 @@ BfModule* BfModule::GetSpecializedMethodModule(const Array<BfProject*>& 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<BfProject*>& projectL
specModule->mParentModule = mainModule;
specModule->mIsSpecializedMethodModuleRoot = true;
specModule->Init();
mainModule->mSpecializedMethodModules[projectList] = specModule;
Array<BfProject*> 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<BfProject*> projectList;
SizedArray<BfProject*, 4> projectList;
bool isUnspecializedPass = (flags & BfGetMethodInstanceFlag_UnspecializedPass) != 0;
if ((isUnspecializedPass) && (methodDef->mGenericParams.size() == 0))

View file

@ -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<BfLocalVariable*> mLocals;
HashSet<BfLocalVarEntry> mLocalVarSet;
Array<BfLocalVariable*, AllocatorBump<BfLocalVariable*> > mLocals;
HashSet<BfLocalVarEntry, AllocatorBump<BfLocalVariable*> > mLocalVarSet;
Array<BfLocalMethod*> mLocalMethods;
Dictionary<String, BfLocalMethod*> mLocalMethodMap;
Dictionary<String, BfLocalMethod*> mLocalMethodCache; // So any lambda 'capturing' and 'processing' stages use the same local method
@ -900,6 +901,11 @@ public:
public:
BfMethodState()
{
mLocals.mAlloc = &mBumpAlloc;
mLocals.Reserve(8);
mLocalVarSet.mAlloc = &mBumpAlloc;
mLocalVarSet.Reserve(8);
mMethodInstance = NULL;
mPrevMethodState = NULL;
mConstResolveState = NULL;
@ -1344,7 +1350,6 @@ public:
bool mIgnoreErrors;
bool mIgnoreWarnings;
bool mSetIllegalSrcPosition;
bool mHadIgnoredError;
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<BfIRValue>& llvmArgs, BfScopeData* scope, BfAstNode* srcNode = NULL, bool bypassVirtual = false, bool doNullCheck = false);
void EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry);
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 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<BfProject*>& projectList);
BfModule* GetSpecializedMethodModule(const SizedArrayImpl<BfProject*>& 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<BfType*>& paramTypes, bool checkBase = false);

View file

@ -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,8 +7694,7 @@ BfType* BfModule::ResolveTypeRef(BfAstNode* astNode, const BfSizedArray<BfTypeRe
return ResolveTypeRef(typeRef, populateType, resolveFlags);
}
// This flow should mirror CastToValue
bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags)
bool BfModule::DoCanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags)
{
BfType* fromType = typedVal.mType;
@ -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,12 +7902,12 @@ 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;
@ -7934,7 +7931,71 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl
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())
{
@ -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()))
@ -8501,7 +8562,7 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl
{
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;
}
// 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)
{
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)
{
@ -8693,11 +8803,10 @@ 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);
@ -8706,11 +8815,10 @@ 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,14 +8954,28 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
}
}
if ((typedVal.mType->IsTypeInstance()) && (toType->IsTypeInstance()))
{
auto fromTypeInstance = typedVal.mType->ToTypeInstance();
auto toTypeInstance = toType->ToTypeInstance();
if ((typedVal.mType->IsValueType()) && (toType->IsValueType()))
{
bool allowCast = false;
if (TypeIsSubTypeOf(fromTypeInstance, toTypeInstance))
allowCast = true;
if (allowCast)
{
if (toType->IsValuelessType())
return BfIRValue::sValueless;
}
}
// ObjectInst|IFace -> object|IFace
if ((typedVal.mType->IsObject() || (typedVal.mType->IsInterface())) && ((toType->IsObject() || (toType->IsInterface()))))
{
bool allowCast = false;
auto fromTypeInstance = typedVal.mType->ToTypeInstance();
auto toTypeInstance = toType->ToTypeInstance();
if (TypeIsSubTypeOf(fromTypeInstance, toTypeInstance))
allowCast = true;
else if ((explicitCast) &&
@ -8868,8 +8990,13 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
}
if (allowCast)
{
if (ignoreWrites)
return mBfIRBuilder->GetFakeVal();
return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
}
}
}
// MethodRef -> Function
if ((typedVal.mType->IsMethodRef()) && (toType->IsFunction()))
@ -8918,8 +9045,12 @@ 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 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<T>
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<A> -> Nullable<B>
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());
}
@ -9654,6 +9792,9 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
if (!castedFromValue)
return BfIRValue();
if (ignoreWrites)
return mBfIRBuilder->GetFakeVal();
SizedArray<BfIRValue, 1> args;
exprEvaluator.PushArg(castedFromValue, args);
auto operatorOut = exprEvaluator.CreateCall(moduleMethodInstance.mMethodInstance, mCompiler->IsSkippingExtraResolveChecks() ? BfIRValue() : moduleMethodInstance.mFunc, false, args);
@ -9675,9 +9816,12 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
isAmbiguousCast |= ((bestFromType != NULL) && (bestToType != NULL));
if (isAmbiguousCast)
{
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<bool> 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,45 +10668,157 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF
{
BfTypeInstance* typeInstance = (BfTypeInstance*)resolvedType;
//auto checkTypeInst = typeInstance;
//auto checkTypeDef = typeInstance->mTypeDef;
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);
//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 checkTypeDef = typeInstance->mTypeDef;
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;
std::function<void(BfTypeDef*, int)> _AddTypeName = [&](BfTypeDef* checkTypeDef, int depth)
{
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;
}
while (checkTypeDef != NULL)
{
if (TypeIsSubTypeOf(checkCurTypeInst, checkTypeInst))
return; // Found outer type
{
endTypeDef = checkTypeDef;
break;
}
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)
BfTypeDef* checkTypeDef = typeInstance->mTypeDef;
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 ((typeNameFlags & BfTypeNameFlag_AddGlobalContainerName) != 0)
@ -10636,26 +10890,6 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF
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())

View file

@ -3627,64 +3627,6 @@ String BfTypeUtils::HashEncode64(uint64 val)
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)
{
return module->GetPrimitiveType(typeCode);

View file

@ -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<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 void PopulateType(BfModule* module, BfType* type);

View file

@ -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<BfIdentifierNode>(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<BfIdentifierNode>(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<BfIdentifierNode>(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)

View file

@ -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">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
@ -218,7 +218,7 @@
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<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>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>