mirror of
https://github.com/beefytech/Beef.git
synced 2025-07-04 15:26:00 +02:00
Initial checkin
This commit is contained in:
parent
c74712dad9
commit
078564ac9e
3242 changed files with 1616395 additions and 0 deletions
1676
IDEHelper/Compiler/BfAst.cpp
Normal file
1676
IDEHelper/Compiler/BfAst.cpp
Normal file
File diff suppressed because it is too large
Load diff
3173
IDEHelper/Compiler/BfAst.h
Normal file
3173
IDEHelper/Compiler/BfAst.h
Normal file
File diff suppressed because it is too large
Load diff
180
IDEHelper/Compiler/BfAstAllocator.cpp
Normal file
180
IDEHelper/Compiler/BfAstAllocator.cpp
Normal file
|
@ -0,0 +1,180 @@
|
|||
#include "BfAstAllocator.h"
|
||||
#include "BfSource.h"
|
||||
#include "BfSystem.h"
|
||||
|
||||
//Craps();
|
||||
|
||||
USING_NS_BF;
|
||||
|
||||
BfBitSet::BfBitSet()
|
||||
{
|
||||
mBits = NULL;
|
||||
}
|
||||
|
||||
BfBitSet::~BfBitSet()
|
||||
{
|
||||
delete [] mBits;
|
||||
}
|
||||
|
||||
void BfBitSet::Init(int numBits)
|
||||
{
|
||||
BF_ASSERT(mBits == NULL);
|
||||
int numInts = (numBits + 31) / 32;
|
||||
mBits = new uint32[numInts];
|
||||
memset(mBits, 0, numInts * 4);
|
||||
}
|
||||
|
||||
|
||||
bool BfBitSet::IsSet(int idx)
|
||||
{
|
||||
return (mBits[idx / 32] & (1 << (idx % 32))) != 0;
|
||||
}
|
||||
|
||||
void BfBitSet::Set(int idx)
|
||||
{
|
||||
mBits[idx / 32] |= (1 << (idx % 32));
|
||||
}
|
||||
|
||||
void BfBitSet::Clear(int idx)
|
||||
{
|
||||
mBits[idx / 32] &= ~(1 << (idx % 32));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BfAstAllocator::BfAstAllocator()
|
||||
{
|
||||
mSourceData = NULL;
|
||||
mCurPtr = NULL;
|
||||
mCurPageEnd = mCurPtr;
|
||||
mLargeAllocSizes = 0;
|
||||
mNumPagesUsed = 0;
|
||||
mUsedSize = 0;
|
||||
}
|
||||
|
||||
BfAstAllocator::~BfAstAllocator()
|
||||
{
|
||||
for (auto addr : mLargeAllocs)
|
||||
delete [] (uint8*)addr;
|
||||
if (mPages.size() != 0)
|
||||
mSourceData->mAstAllocManager->FreePages(mPages);
|
||||
}
|
||||
|
||||
void BfAstAllocator::InitChunkHead(int wantSize)
|
||||
{
|
||||
mCurPtr = mSourceData->mAstAllocManager->AllocPage();
|
||||
mPages.push_back(mCurPtr);
|
||||
mCurPageEnd = mCurPtr + BfAstAllocManager::PAGE_SIZE;
|
||||
mNumPagesUsed++;
|
||||
#ifdef BF_AST_ALLOCATOR_USE_PAGES
|
||||
BfAstPageHeader* pageHeader = (BfAstPageHeader*)mCurPtr;
|
||||
pageHeader->mSourceData = mSourceData;
|
||||
BF_ASSERT(sizeof(BfAstPageHeader) <= 16);
|
||||
mCurPtr += 16;
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BfAstAllocManager::BfAstAllocManager()
|
||||
{
|
||||
#ifdef BF_AST_ALLOCATOR_USE_PAGES
|
||||
mFreePageCount = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
BfAstAllocManager::~BfAstAllocManager()
|
||||
{
|
||||
#ifdef BF_AST_ALLOCATOR_USE_PAGES
|
||||
for (int chunkIdx = (int)mAllocChunks.size() - 1; chunkIdx >= 0; chunkIdx--)
|
||||
{
|
||||
auto chunk = mAllocChunks[chunkIdx];
|
||||
::VirtualFree(chunk, 0, MEM_RELEASE);
|
||||
//BfLog("BfAstAllocManager free %p\n", chunk);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//TODO: Remove this
|
||||
//static int gAstChunkAllocCount = 0;
|
||||
uint8* BfAstAllocManager::AllocPage()
|
||||
{
|
||||
#ifdef BF_AST_ALLOCATOR_USE_PAGES
|
||||
AutoCrit autoCrit(mCritSect);
|
||||
|
||||
if (mFreePageCount != 0)
|
||||
{
|
||||
mFreePageCount--;
|
||||
return (uint8*)mFreePages.PopFront();
|
||||
}
|
||||
|
||||
BF_ASSERT(mFreePages.mHead == NULL);
|
||||
|
||||
//auto newChunk = (uint8*)::VirtualAlloc((void*)(0x4200000000 + gAstChunkAllocCount*CHUNK_SIZE), CHUNK_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
//gAstChunkAllocCount++;
|
||||
|
||||
auto newChunk = (uint8*)::VirtualAlloc(NULL, CHUNK_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
BF_ASSERT(newChunk != NULL);
|
||||
BF_ASSERT(((intptr)newChunk & (PAGE_SIZE - 1)) == 0);
|
||||
mAllocChunks.push_back(newChunk);
|
||||
|
||||
//BfLog("BfAstAllocManager alloc %p\n", newChunk);
|
||||
|
||||
for (uint8* ptr = newChunk; ptr < newChunk + CHUNK_SIZE; ptr += PAGE_SIZE)
|
||||
{
|
||||
auto freePage = (BfAstFreePage*)ptr;
|
||||
mFreePages.PushBack(freePage);
|
||||
mFreePageCount++;
|
||||
}
|
||||
|
||||
mFreePageCount--;
|
||||
return (uint8*)mFreePages.PopFront();
|
||||
#else
|
||||
return new uint8[PAGE_SIZE];
|
||||
#endif
|
||||
}
|
||||
|
||||
void BfAstAllocManager::FreePage(uint8* page)
|
||||
{
|
||||
#ifdef BF_AST_ALLOCATOR_USE_PAGES
|
||||
AutoCrit autoCrit(mCritSect);
|
||||
mFreePageCount++;
|
||||
auto pageVal = (BfAstFreePage*)page;
|
||||
pageVal->mNext = NULL;
|
||||
mFreePages.PushFront(pageVal);
|
||||
#else
|
||||
delete[] page;
|
||||
#endif
|
||||
}
|
||||
|
||||
void BfAstAllocManager::FreePages(Array<uint8*> pages)
|
||||
{
|
||||
#ifdef BF_AST_ALLOCATOR_USE_PAGES
|
||||
AutoCrit autoCrit(mCritSect);
|
||||
for (auto page : pages)
|
||||
{
|
||||
mFreePageCount++;
|
||||
auto pageVal = (BfAstFreePage*)page;
|
||||
pageVal->mNext = NULL;
|
||||
mFreePages.PushFront(pageVal);
|
||||
}
|
||||
#else
|
||||
for (auto page : pages)
|
||||
delete[] page;
|
||||
#endif
|
||||
}
|
||||
|
||||
void BfAstAllocManager::GetStats(int& allocPages, int& usedPages)
|
||||
{
|
||||
#ifdef BF_AST_ALLOCATOR_USE_PAGES
|
||||
AutoCrit autoCrit(mCritSect);
|
||||
|
||||
//mShowStats = true;
|
||||
|
||||
allocPages = (int)mAllocChunks.size() * CHUNK_SIZE / PAGE_SIZE;
|
||||
usedPages = allocPages - mFreePageCount;
|
||||
#else
|
||||
allocPages = 0;
|
||||
usedPages = 0;
|
||||
#endif
|
||||
}
|
222
IDEHelper/Compiler/BfAstAllocator.h
Normal file
222
IDEHelper/Compiler/BfAstAllocator.h
Normal file
|
@ -0,0 +1,222 @@
|
|||
#pragma once
|
||||
|
||||
//#define BF_USE_NEAR_NODE_REF
|
||||
|
||||
#include "BeefySysLib/Common.h"
|
||||
#include "BeefySysLib/util/CritSect.h"
|
||||
#include "BeefySysLib/util/SLIList.h"
|
||||
#include "../Beef/BfCommon.h"
|
||||
|
||||
#ifdef BF_PLATFORM_WINDOWS
|
||||
#define BF_AST_ALLOCATOR_USE_PAGES
|
||||
#endif
|
||||
|
||||
/*#pragma warning(push)
|
||||
#pragma warning(disable:4141)
|
||||
#pragma warning(disable:4146)
|
||||
#pragma warning(disable:4291)
|
||||
#pragma warning(disable:4244)
|
||||
#pragma warning(disable:4267)
|
||||
#pragma warning(disable:4624)
|
||||
#pragma warning(disable:4800)
|
||||
#pragma warning(disable:4996)
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
#pragma warning(pop)*/
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
class BfSource;
|
||||
class BfSourceData;
|
||||
|
||||
class BfBitSet
|
||||
{
|
||||
public:
|
||||
uint32* mBits;
|
||||
|
||||
public:
|
||||
BfBitSet();
|
||||
~BfBitSet();
|
||||
|
||||
void Init(int numBits);
|
||||
bool IsSet(int idx);
|
||||
void Set(int idx);
|
||||
void Clear(int idx);
|
||||
};
|
||||
|
||||
#ifdef BF_AST_ALLOCATOR_USE_PAGES
|
||||
class BfAstPageHeader
|
||||
{
|
||||
public:
|
||||
BfSourceData* mSourceData;
|
||||
};
|
||||
#endif
|
||||
|
||||
class BfAstAllocChunk;
|
||||
class BfAstAllocManager;
|
||||
|
||||
|
||||
struct BfAstFreePage
|
||||
{
|
||||
BfAstFreePage* mNext;
|
||||
};
|
||||
|
||||
class BfAstAllocManager
|
||||
{
|
||||
public:
|
||||
static const int CHUNK_SIZE = 1024*1024;
|
||||
static const int PAGE_SIZE = 4096;
|
||||
|
||||
#ifdef BF_AST_ALLOCATOR_USE_PAGES
|
||||
CritSect mCritSect;
|
||||
SLIList<BfAstFreePage*> mFreePages;
|
||||
int mFreePageCount;
|
||||
Array<uint8*> mAllocChunks;
|
||||
#endif
|
||||
|
||||
public:
|
||||
BfAstAllocManager();
|
||||
~BfAstAllocManager();
|
||||
|
||||
uint8* AllocPage();
|
||||
void FreePage(uint8* page);
|
||||
void FreePages(Array<uint8*> pages);
|
||||
void GetStats(int& allocPages, int& usedPages);
|
||||
};
|
||||
|
||||
// #ifdef BUMPALLOC_TRACKALLOCS
|
||||
// struct BumpAllocTrackedEntry
|
||||
// {
|
||||
// int mCount;
|
||||
// int mSize;
|
||||
//
|
||||
// BumpAllocTrackedEntry()
|
||||
// {
|
||||
// mCount = 0;
|
||||
// mSize = 0;
|
||||
// }
|
||||
// };
|
||||
// #endif
|
||||
|
||||
class BfAstAllocator
|
||||
{
|
||||
public:
|
||||
static const int LARGE_ALLOC_SIZE = 2048;
|
||||
BfSourceData* mSourceData;
|
||||
uint8* mCurPtr;
|
||||
uint8* mCurPageEnd;
|
||||
Array<void*> mLargeAllocs;
|
||||
Array<uint8*> mPages;
|
||||
int mLargeAllocSizes;
|
||||
int mNumPagesUsed;
|
||||
int mUsedSize;
|
||||
#ifdef BUMPALLOC_TRACKALLOCS
|
||||
Dictionary<String, BumpAllocTrackedEntry> mTrackedAllocs;
|
||||
#endif
|
||||
|
||||
public:
|
||||
BfAstAllocator();
|
||||
~BfAstAllocator();
|
||||
|
||||
void InitChunkHead(int wantSize);
|
||||
|
||||
int GetAllocSize() const
|
||||
{
|
||||
return (int)(((mPages.size() - 1) * BfAstAllocManager::PAGE_SIZE) + (BfAstAllocManager::PAGE_SIZE - (mCurPageEnd - mCurPtr)));
|
||||
}
|
||||
|
||||
int GetTotalAllocSize() const
|
||||
{
|
||||
return (int)mPages.size() * BfAstAllocManager::PAGE_SIZE;
|
||||
}
|
||||
|
||||
int CalcUsedSize() const
|
||||
{
|
||||
return GetAllocSize();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* Alloc(int extraBytes = 0)
|
||||
{
|
||||
int alignSize = alignof(T);
|
||||
mCurPtr = (uint8*)(((intptr)mCurPtr + alignSize - 1) & ~(alignSize - 1));
|
||||
int wantSize = sizeof(T) + extraBytes;
|
||||
|
||||
#ifdef BUMPALLOC_TRACKALLOCS
|
||||
const char* name = typeid(T).name();
|
||||
BumpAllocTrackedEntry* allocSizePtr;
|
||||
mTrackedAllocs.TryAdd(name, NULL, &allocSizePtr);
|
||||
allocSizePtr->mCount++;
|
||||
allocSizePtr->mSize += wantSize;
|
||||
#endif
|
||||
|
||||
if (mCurPtr + wantSize >= mCurPageEnd)
|
||||
InitChunkHead(wantSize);
|
||||
memset(mCurPtr, 0, wantSize);
|
||||
T* retVal = new (mCurPtr) T();
|
||||
mCurPtr += wantSize;
|
||||
|
||||
#ifndef BF_AST_ALLOCATOR_USE_PAGES
|
||||
retVal->mSourceData = this->mSourceData;
|
||||
#endif
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
uint8* AllocBytes(int wantSize, int alignSize, const char* dbgName = "AllocBytes")
|
||||
{
|
||||
#ifdef BUMPALLOC_TRACKALLOCS
|
||||
BumpAllocTrackedEntry* allocSizePtr;
|
||||
mTrackedAllocs.TryAdd(dbgName, NULL, &allocSizePtr);
|
||||
allocSizePtr->mCount++;
|
||||
allocSizePtr->mSize += wantSize;
|
||||
#endif
|
||||
|
||||
#ifndef BF_USE_NEAR_NODE_REF
|
||||
if (wantSize >= LARGE_ALLOC_SIZE)
|
||||
{
|
||||
mLargeAllocSizes += wantSize;
|
||||
uint8* addr = new uint8[wantSize];
|
||||
mLargeAllocs.push_back(addr);
|
||||
return addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
mCurPtr = (uint8*)(((intptr)mCurPtr + alignSize - 1) & ~(alignSize - 1));
|
||||
if (mCurPtr + wantSize >= mCurPageEnd)
|
||||
InitChunkHead(wantSize);
|
||||
memset(mCurPtr, 0, wantSize);
|
||||
uint8* retVal = mCurPtr;
|
||||
mCurPtr += wantSize;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
uint8* AllocBytes(int wantSize, const char* dbgName = "AllocBytes")
|
||||
{
|
||||
#ifdef BUMPALLOC_TRACKALLOCS
|
||||
BumpAllocTrackedEntry* allocSizePtr;
|
||||
mTrackedAllocs.TryAdd(dbgName, NULL, &allocSizePtr);
|
||||
allocSizePtr->mCount++;
|
||||
allocSizePtr->mSize += wantSize;
|
||||
#endif
|
||||
|
||||
if (wantSize >= LARGE_ALLOC_SIZE)
|
||||
{
|
||||
uint8* addr = new uint8[wantSize];
|
||||
mLargeAllocs.push_back(addr);
|
||||
return addr;
|
||||
}
|
||||
|
||||
if (mCurPtr + wantSize >= mCurPageEnd)
|
||||
InitChunkHead(wantSize);
|
||||
memset(mCurPtr, 0, wantSize);
|
||||
uint8* retVal = mCurPtr;
|
||||
mCurPtr += wantSize;
|
||||
return retVal;
|
||||
}
|
||||
};
|
||||
|
||||
NS_BF_END
|
||||
|
||||
|
2279
IDEHelper/Compiler/BfAutoComplete.cpp
Normal file
2279
IDEHelper/Compiler/BfAutoComplete.cpp
Normal file
File diff suppressed because it is too large
Load diff
250
IDEHelper/Compiler/BfAutoComplete.h
Normal file
250
IDEHelper/Compiler/BfAutoComplete.h
Normal file
|
@ -0,0 +1,250 @@
|
|||
#pragma once
|
||||
|
||||
#include "BfCompiler.h"
|
||||
#include "BfSourceClassifier.h"
|
||||
#include "BfResolvePass.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
class BfMethodInstance;
|
||||
class BfLocalVariable;
|
||||
|
||||
class AutoCompleteEntry
|
||||
{
|
||||
public:
|
||||
const char* mEntryType;
|
||||
const char* mDisplay;
|
||||
BfCommentNode* mDocumentation;
|
||||
|
||||
public:
|
||||
AutoCompleteEntry()
|
||||
{
|
||||
}
|
||||
|
||||
AutoCompleteEntry(const char* entryType, const char* display)
|
||||
{
|
||||
mEntryType = entryType;
|
||||
mDisplay = display;
|
||||
mDocumentation = NULL;
|
||||
}
|
||||
|
||||
AutoCompleteEntry(const char* entryType, const char* display, BfCommentNode* documentation)
|
||||
{
|
||||
mEntryType = entryType;
|
||||
mDisplay = display;
|
||||
mDocumentation = documentation;
|
||||
}
|
||||
|
||||
AutoCompleteEntry(const char* entryType, const StringImpl& display)
|
||||
{
|
||||
mEntryType = entryType;
|
||||
mDisplay = display.c_str();
|
||||
mDocumentation = NULL;
|
||||
}
|
||||
|
||||
AutoCompleteEntry(const char* entryType, const StringImpl& display, BfCommentNode* documentation)
|
||||
{
|
||||
mEntryType = entryType;
|
||||
mDisplay = display.c_str();
|
||||
mDocumentation = documentation;
|
||||
}
|
||||
|
||||
bool operator==(const AutoCompleteEntry& other) const
|
||||
{
|
||||
return strcmp(mDisplay, other.mDisplay) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
NS_BF_END
|
||||
|
||||
template <>
|
||||
struct BeefHash<Beefy::AutoCompleteEntry>
|
||||
{
|
||||
size_t operator()(const Beefy::AutoCompleteEntry& val)
|
||||
{
|
||||
intptr hash = 0;
|
||||
const char* curPtr = val.mDisplay;
|
||||
while (true)
|
||||
{
|
||||
char c = *(curPtr++);
|
||||
if (c == 0)
|
||||
break;
|
||||
hash = (hash ^ (intptr)c) - hash;
|
||||
}
|
||||
|
||||
return (size_t)hash;
|
||||
}
|
||||
};
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
class AutoCompleteBase
|
||||
{
|
||||
public:
|
||||
class EntryLess
|
||||
{
|
||||
public:
|
||||
bool operator()(const AutoCompleteEntry& left, const AutoCompleteEntry& right)
|
||||
{
|
||||
auto result = _stricmp(left.mDisplay, right.mDisplay);
|
||||
if (result == 0)
|
||||
result = strcmp(left.mDisplay, right.mDisplay);
|
||||
return result < 0;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
BumpAllocator mAlloc;
|
||||
HashSet<AutoCompleteEntry> mEntriesSet;
|
||||
|
||||
bool mIsGetDefinition;
|
||||
bool mIsAutoComplete;
|
||||
int mInsertStartIdx;
|
||||
int mInsertEndIdx;
|
||||
|
||||
bool DoesFilterMatch(const char* entry, const char* filter);
|
||||
AutoCompleteEntry* AddEntry(const AutoCompleteEntry& entry, const StringImpl& filter);
|
||||
AutoCompleteEntry* AddEntry(const AutoCompleteEntry& entry);
|
||||
|
||||
AutoCompleteBase();
|
||||
virtual ~AutoCompleteBase();
|
||||
|
||||
void Clear();
|
||||
};
|
||||
|
||||
class BfAutoComplete : public AutoCompleteBase
|
||||
{
|
||||
public:
|
||||
class MethodMatchEntry
|
||||
{
|
||||
public:
|
||||
BfMethodDef* mMethodDef;
|
||||
BfFieldInstance* mPayloadEnumField;
|
||||
BfTypeInstance* mTypeInstance;
|
||||
BfTypeVector mGenericArguments;
|
||||
BfMethodInstance* mCurMethodInstance;
|
||||
|
||||
MethodMatchEntry()
|
||||
{
|
||||
mMethodDef = NULL;
|
||||
mPayloadEnumField = NULL;
|
||||
mTypeInstance = NULL;
|
||||
mCurMethodInstance = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
class MethodMatchInfo
|
||||
{
|
||||
public:
|
||||
BfTypeInstance* mCurTypeInstance;
|
||||
BfMethodInstance* mCurMethodInstance;
|
||||
Array<MethodMatchEntry> mInstanceList;
|
||||
int mInvocationSrcIdx;
|
||||
int mBestIdx;
|
||||
int mPrevBestIdx;
|
||||
bool mHadExactMatch;
|
||||
int mMostParamsMatched;
|
||||
Array<int> mSrcPositions; // start, commas, end
|
||||
|
||||
public:
|
||||
MethodMatchInfo()
|
||||
{
|
||||
mInvocationSrcIdx = -1;
|
||||
mCurTypeInstance = NULL;
|
||||
mCurMethodInstance = NULL;
|
||||
mBestIdx = 0;
|
||||
mPrevBestIdx = -1;
|
||||
mHadExactMatch = false;
|
||||
mMostParamsMatched = 0;
|
||||
}
|
||||
|
||||
~MethodMatchInfo()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
BfModule* mModule;
|
||||
BfCompiler* mCompiler;
|
||||
BfSystem* mSystem;
|
||||
MethodMatchInfo* mMethodMatchInfo;
|
||||
bool mIsCapturingMethodMatchInfo;
|
||||
String mDefaultSelection;
|
||||
String mVarTypeName;
|
||||
String mDocumentationEntryName;
|
||||
BfAstNode* mGetDefinitionNode;
|
||||
BfResolveType mResolveType;
|
||||
BfTypeInstance* mShowAttributeProperties;
|
||||
BfIdentifierNode* mIdentifierUsed;
|
||||
bool mIgnoreFixits;
|
||||
bool mHasFriendSet;
|
||||
bool mUncertain; // May be an unknown identifier, do not aggressively autocomplete
|
||||
int mCursorLineStart;
|
||||
int mCursorLineEnd;
|
||||
|
||||
//BfMethodInstance* mReplaceMethodInstance;
|
||||
|
||||
int mReplaceLocalId;
|
||||
//int mDefMethodIdx;
|
||||
BfMethodDef* mDefMethod;
|
||||
BfTypeDef* mDefType;
|
||||
BfFieldDef* mDefField;
|
||||
BfPropertyDef* mDefProp;
|
||||
int mDefMethodGenericParamIdx;
|
||||
int mDefTypeGenericParamIdx;
|
||||
|
||||
public:
|
||||
bool CheckProtection(BfProtection protection, bool allowProtected, bool allowPrivate);
|
||||
String GetFilter(BfAstNode* node);
|
||||
const char* GetTypeName(BfType* type);
|
||||
int GetCursorIdx(BfAstNode* node);
|
||||
bool IsAutocompleteNode(BfAstNode* node, int lengthAdd = 0, int startAdd = 0);
|
||||
bool IsAutocompleteNode(BfAstNode* startNode, BfAstNode* endNode, int lengthAdd = 0, int startAdd = 0);
|
||||
bool IsAutocompleteLineNode(BfAstNode* node);
|
||||
BfTypedValue LookupTypeRefOrIdentifier(BfAstNode* node, bool* isStatic, BfEvalExprFlags evalExprFlags = BfEvalExprFlags_None, BfType* expectingType = NULL);
|
||||
void SetDefinitionLocation(BfAstNode* astNode, bool force = false);
|
||||
bool IsAttribute(BfTypeInstance* typeInst);
|
||||
void AddMethod(BfMethodDeclaration* methodDecl, const StringImpl& methodName, const StringImpl& filter);
|
||||
void AddTypeDef(BfTypeDef* typeDef, const StringImpl& filter, bool onlyAttribute = false);
|
||||
void AddInnerTypes(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate);
|
||||
void AddCurrentTypes(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate, bool onlyAttribute);
|
||||
void AddTypeMembers(BfTypeInstance* typeInst, bool addStatic, bool addNonStatic, const StringImpl& filter, BfTypeInstance* startType, bool allowInterfaces, bool allowImplicitThis);
|
||||
void AddSelfResultTypeMembers(BfTypeInstance* typeInst, BfTypeInstance* selfType, const StringImpl& filter, bool allowPrivate);
|
||||
bool InitAutocomplete(BfAstNode* dotNode, BfAstNode* nameNode, String& filter);
|
||||
void AddEnumTypeMembers(BfTypeInstance* typeInst, const StringImpl& filter, bool allowProtected, bool allowPrivate);
|
||||
void AddTopLevelNamespaces(BfIdentifierNode* identifierNode);
|
||||
void AddTopLevelTypes(BfIdentifierNode* identifierNode, bool onlyAttribute = false);
|
||||
void AddOverrides(const StringImpl& filter);
|
||||
void UpdateReplaceData();
|
||||
void AddTypeInstanceEntry(BfTypeInstance* typeInst);
|
||||
void CheckDocumentation(AutoCompleteEntry* entry, BfCommentNode* documentation);
|
||||
|
||||
public:
|
||||
BfAutoComplete(BfResolveType resolveType = BfResolveType_Autocomplete);
|
||||
~BfAutoComplete();
|
||||
|
||||
void SetModule(BfModule* module);
|
||||
void Clear();
|
||||
void RemoveMethodMatchInfo();
|
||||
void ClearMethodMatchEntries();
|
||||
|
||||
void CheckIdentifier(BfIdentifierNode* identifierNode, bool isInExpression = false, bool isUsingDirective = false);
|
||||
bool CheckMemberReference(BfAstNode* target, BfAstNode* dotToken, BfAstNode* memberName, bool onlyShowTypes = false, BfType* expectingType = NULL, bool isUsingDirective = false, bool onlyAttribute = false);
|
||||
void CheckTypeRef(BfTypeReference* typeRef, bool mayBeIdentifier, bool isInExpression = false, bool onlyAttribute = false);
|
||||
void CheckAttributeTypeRef(BfTypeReference* typeRef);
|
||||
void CheckInvocation(BfAstNode* invocationNode, BfTokenNode* openParen, BfTokenNode* closeParen, const BfSizedArray<BfTokenNode*>& commas);
|
||||
void CheckNode(BfAstNode* node);
|
||||
void CheckMethod(BfMethodDeclaration* methodDeclaration, bool isLocalMethod);
|
||||
void CheckProperty(BfPropertyDeclaration* propertyDeclaration);
|
||||
void CheckVarResolution(BfAstNode* varTypeRef, BfType* resolvedTypeRef);
|
||||
void CheckLocalDef(BfIdentifierNode* identifierNode, BfLocalVariable* varDecl);
|
||||
void CheckLocalRef(BfIdentifierNode* identifierNode, BfLocalVariable* varDecl);
|
||||
void CheckFieldRef(BfIdentifierNode* identifierNode, BfFieldInstance* fieldInst);
|
||||
void CheckLabel(BfIdentifierNode* identifierNode, BfAstNode* precedingNode = NULL);
|
||||
void CheckEmptyStart(BfAstNode* prevNode, BfType* type);
|
||||
bool CheckFixit(BfAstNode* node);
|
||||
|
||||
void FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType, const StringImpl& fieldName, bool isStatic, BfTypeInstance* referencedFrom);
|
||||
};
|
||||
|
||||
NS_BF_END
|
1081
IDEHelper/Compiler/BfCodeGen.cpp
Normal file
1081
IDEHelper/Compiler/BfCodeGen.cpp
Normal file
File diff suppressed because it is too large
Load diff
217
IDEHelper/Compiler/BfCodeGen.h
Normal file
217
IDEHelper/Compiler/BfCodeGen.h
Normal file
|
@ -0,0 +1,217 @@
|
|||
#pragma once
|
||||
|
||||
#include "BeefySysLib/util/PerfTimer.h"
|
||||
#include "BeefySysLib/util/CritSect.h"
|
||||
#include "BeefySysLib/Common.h"
|
||||
#include "BeefySysLib/util/PerfTimer.h"
|
||||
#include "BfAst.h"
|
||||
#include "BfSystem.h"
|
||||
|
||||
namespace llvm
|
||||
{
|
||||
class Module;
|
||||
class LLVMContext;
|
||||
}
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
class BfModule;
|
||||
|
||||
enum BfCodeGenResultType
|
||||
{
|
||||
BfCodeGenResult_NotDone,
|
||||
BfCodeGenResult_Done,
|
||||
BfCodeGenResult_DoneCached,
|
||||
BfCodeGenResult_Failed,
|
||||
BfCodeGenResult_Aborted,
|
||||
};
|
||||
struct BfCodeGenResult
|
||||
{
|
||||
static const int kErrorMsgBufSize = 1024;
|
||||
|
||||
BfCodeGenResultType mType;
|
||||
char mErrorMsgBuf[kErrorMsgBufSize]; // not using String etc. since can be modified cross-process
|
||||
int mErrorMsgBufLen;
|
||||
|
||||
BfCodeGenResult() { mType = BfCodeGenResult_NotDone; mErrorMsgBufLen = 0; }
|
||||
};
|
||||
|
||||
class BfCodeGenErrorEntry
|
||||
{
|
||||
public:
|
||||
BfModule* mSrcModule;
|
||||
String mOutFileName;
|
||||
Array<String> mErrorMessages;
|
||||
};
|
||||
|
||||
|
||||
class BfCodeGenRequest
|
||||
{
|
||||
public:
|
||||
BfModule* mSrcModule;
|
||||
BfCodeGenOptions mOptions;
|
||||
BfCodeGenResult mResult;
|
||||
Array<uint8> mOutBuffer;
|
||||
BfSizedArray<uint8> mData;
|
||||
String mOutFileName;
|
||||
|
||||
BfCodeGenResult* mExternResultPtr;
|
||||
|
||||
public:
|
||||
BfCodeGenRequest()
|
||||
{
|
||||
mSrcModule = NULL;
|
||||
mResult.mType = BfCodeGenResult_NotDone;
|
||||
mResult.mErrorMsgBufLen = 0;
|
||||
mExternResultPtr = NULL;
|
||||
}
|
||||
|
||||
~BfCodeGenRequest()
|
||||
{
|
||||
}
|
||||
|
||||
void DbgSaveData();
|
||||
};
|
||||
|
||||
class BfCodeGen;
|
||||
|
||||
class BfCodeGenThread
|
||||
{
|
||||
public:
|
||||
BfCodeGen* mCodeGen;
|
||||
int mThreadIdx;
|
||||
|
||||
//std::vector<BfCodeGenRequest*> mRequests;
|
||||
volatile bool mShuttingDown;
|
||||
volatile bool mRunning;
|
||||
|
||||
public:
|
||||
bool RawWriteObjectFile(llvm::Module* module, const StringImpl& outFileName, const BfCodeGenOptions& codeGenOptions);
|
||||
|
||||
public:
|
||||
BfCodeGenThread();
|
||||
~BfCodeGenThread();
|
||||
|
||||
void RunLoop();
|
||||
void Shutdown();
|
||||
|
||||
void Start();
|
||||
};
|
||||
|
||||
class BfCodeGenFileData
|
||||
{
|
||||
public:
|
||||
Val128 mIRHash; // Equal when exact IR bits are equal
|
||||
Val128 mIROrderedHash; // Equal when isomorphic (when alphabetically reordered functions hash equally)
|
||||
bool mLastWasObjectWrite;
|
||||
};
|
||||
|
||||
class BfCodeGenDirectoryData
|
||||
{
|
||||
public:
|
||||
BfCodeGen* mCodeGen;
|
||||
Dictionary<String, BfCodeGenFileData> mFileMap;
|
||||
String mDirectoryName;
|
||||
bool mDirty;
|
||||
bool mVerified;
|
||||
int64 mFileTime;
|
||||
String mError;
|
||||
bool mFileFailed;
|
||||
|
||||
public:
|
||||
BfCodeGenDirectoryData()
|
||||
{
|
||||
mCodeGen = NULL;
|
||||
mDirty = true;
|
||||
mVerified = true;
|
||||
mFileTime = 0;
|
||||
mFileFailed = false;
|
||||
}
|
||||
|
||||
String GetDataFileName();
|
||||
void Read();
|
||||
void Write();
|
||||
void Verify();
|
||||
void Clear();
|
||||
bool CheckCache(const StringImpl& fileName, Val128 hash, Val128* outOrderedHash, bool disallowObjectWrite);
|
||||
void SetHash(const StringImpl& fileName, Val128 hash, Val128 orderedHash, bool isObjectWrite);
|
||||
void ClearHash(const StringImpl& fileName);
|
||||
void FileFailed();
|
||||
};
|
||||
|
||||
class BfCodeGenFileEntry
|
||||
{
|
||||
public:
|
||||
String mFileName;
|
||||
BfModule* mModule;
|
||||
BfProject* mProject;
|
||||
bool mWasCached;
|
||||
bool mModuleHotReferenced; // Only applicable for hot loading
|
||||
};
|
||||
|
||||
class BfCodeGen
|
||||
{
|
||||
public:
|
||||
typedef int (BF_CALLTYPE* ClearCacheFunc)();
|
||||
typedef int (BF_CALLTYPE* GetVersionFunc)();
|
||||
typedef void (BF_CALLTYPE* KillFunc)();
|
||||
typedef void (BF_CALLTYPE* CancelFunc)();
|
||||
typedef void (BF_CALLTYPE* FinishFunc)();
|
||||
typedef void (BF_CALLTYPE* GenerateObjFunc)(const void* ptr, int size, const char* outFileName, BfCodeGenResult* resultPtr, const BfCodeGenOptions& options);
|
||||
|
||||
public:
|
||||
BfpDynLib* mReleaseModule;
|
||||
bool mAttemptedReleaseThunkLoad;
|
||||
bool mIsUsingReleaseThunk;
|
||||
ClearCacheFunc mClearCacheFunc;
|
||||
GetVersionFunc mGetVersionFunc;
|
||||
KillFunc mKillFunc;
|
||||
CancelFunc mCancelFunc;
|
||||
FinishFunc mFinishFunc;
|
||||
GenerateObjFunc mGenerateObjFunc;
|
||||
|
||||
Val128 mBackendHash;
|
||||
int mMaxThreadCount;
|
||||
CritSect mThreadsCritSect;
|
||||
Array<BfCodeGenThread*> mThreads;
|
||||
Array<BfCodeGenThread*> mOldThreads;
|
||||
Deque<BfCodeGenRequest*> mRequests;
|
||||
CritSect mPendingRequestCritSect;
|
||||
Deque<BfCodeGenRequest*> mPendingRequests;
|
||||
SyncEvent mRequestEvent;
|
||||
int mRequestIdx;
|
||||
SyncEvent mDoneEvent;
|
||||
|
||||
int mQueuedCount;
|
||||
int mCompletionCount;
|
||||
|
||||
Array<BfCodeGenErrorEntry> mFailedRequests;
|
||||
Array<BfCodeGenFileEntry> mCodeGenFiles;
|
||||
|
||||
CritSect mCacheCritSect;
|
||||
bool mDisableCacheReads;
|
||||
Dictionary<String, BfCodeGenDirectoryData*> mDirectoryCache;
|
||||
|
||||
public:
|
||||
void SetMaxThreads(int maxThreads);
|
||||
void BindReleaseThunks();
|
||||
void ClearResults();
|
||||
void DoWriteObjectFile(BfCodeGenRequest* codeGenRequest, const void* ptr, int size, const StringImpl& outFileName, BfCodeGenResult* externResultPtr);
|
||||
bool ExternWriteObjectFile(BfCodeGenRequest* codeGenRequest);
|
||||
void ClearOldThreads(bool waitForThread);
|
||||
void ClearBuildCache();
|
||||
void RequestComplete(BfCodeGenRequest* request);
|
||||
void ProcessErrors(BfPassInstance* passInstance, bool canceled);
|
||||
|
||||
public:
|
||||
BfCodeGen();
|
||||
~BfCodeGen();
|
||||
|
||||
void ResetStats();
|
||||
void UpdateStats();
|
||||
void WriteObjectFile(BfModule* module, const StringImpl& outFileName, const BfCodeGenOptions& options);
|
||||
void Cancel();
|
||||
bool Finish();
|
||||
};
|
||||
|
||||
NS_BF_END
|
8127
IDEHelper/Compiler/BfCompiler.cpp
Normal file
8127
IDEHelper/Compiler/BfCompiler.cpp
Normal file
File diff suppressed because it is too large
Load diff
451
IDEHelper/Compiler/BfCompiler.h
Normal file
451
IDEHelper/Compiler/BfCompiler.h
Normal file
|
@ -0,0 +1,451 @@
|
|||
#pragma once
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4141)
|
||||
#pragma warning(disable:4146)
|
||||
#pragma warning(disable:4291)
|
||||
#pragma warning(disable:4244)
|
||||
#pragma warning(disable:4267)
|
||||
#pragma warning(disable:4624)
|
||||
#pragma warning(disable:4800)
|
||||
|
||||
#include "BeefySysLib/Common.h"
|
||||
#include "BeefySysLib/util/CritSect.h"
|
||||
#include "BeefySysLib/util/PerfTimer.h"
|
||||
#include "BeefySysLib/util/String.h"
|
||||
#include "BfAst.h"
|
||||
#include "BfSystem.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/IR/IRBuilder.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/IR/DIBuilder.h"
|
||||
#include "llvm/IR/DebugInfo.h"
|
||||
#include "llvm/IR/Argument.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "BfResolvedTypeUtils.h"
|
||||
#include <unordered_set>
|
||||
#include "BfContext.h"
|
||||
#include "BfCodeGen.h"
|
||||
#include "BfMangler.h"
|
||||
|
||||
#pragma warning(pop)
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
class BfType;
|
||||
class BfResolvedType;
|
||||
class BfTypeInstance;
|
||||
class BfModule;
|
||||
class BfFileInstance;
|
||||
class BfAutoComplete;
|
||||
class BfMethodInstance;
|
||||
class BfSourceClassifier;
|
||||
class BfResolvePassData;
|
||||
|
||||
enum BfCompileOnDemandKind
|
||||
{
|
||||
BfCompileOnDemandKind_AlwaysInclude,
|
||||
BfCompileOnDemandKind_ResolveUnused,
|
||||
BfCompileOnDemandKind_SkipUnused
|
||||
};
|
||||
|
||||
class BfCompiler
|
||||
{
|
||||
public:
|
||||
enum CompileState
|
||||
{
|
||||
CompileState_None,
|
||||
CompileState_Normal,
|
||||
CompileState_Unreified,
|
||||
CompileState_VData
|
||||
};
|
||||
|
||||
struct Stats
|
||||
{
|
||||
int mTotalTypes;
|
||||
|
||||
int mMethodDeclarations;
|
||||
int mTypesPopulated;
|
||||
int mMethodsProcessed;
|
||||
int mUnreifiedMethodsProcessed;
|
||||
|
||||
int mQueuedTypesProcessed;
|
||||
int mTypesQueued;
|
||||
int mTypesDeleted;
|
||||
int mMethodsQueued;
|
||||
|
||||
int mModulesStarted;
|
||||
int mModulesFinished;
|
||||
|
||||
int mModulesReified;
|
||||
int mModulesUnreified;
|
||||
|
||||
int mReifiedModuleCount;
|
||||
int mIRBytes;
|
||||
int mConstBytes;
|
||||
};
|
||||
Stats mStats;
|
||||
|
||||
struct Options
|
||||
{
|
||||
BfProject* mHotProject;
|
||||
int mHotCompileIdx;
|
||||
|
||||
int32 mForceRebuildIdx;
|
||||
BfCompileOnDemandKind mCompileOnDemandKind;
|
||||
BfMachineType mMachineType;
|
||||
BfToolsetType mToolsetType;
|
||||
BfSIMDSetting mSIMDSetting;
|
||||
int mMaxWorkerThreads;
|
||||
String mMallocLinkName;
|
||||
String mFreeLinkName;
|
||||
bool mIncrementalBuild;
|
||||
|
||||
bool mEmitDebugInfo;
|
||||
bool mEmitLineInfo;
|
||||
|
||||
bool mNoFramePointerElim;
|
||||
bool mInitLocalVariables;
|
||||
bool mRuntimeChecks;
|
||||
bool mAllowStructByVal;
|
||||
bool mEmitDynamicCastCheck;
|
||||
|
||||
bool mAllowHotSwapping;
|
||||
bool mObjectHasDebugFlags;
|
||||
bool mEnableRealtimeLeakCheck;
|
||||
bool mEmitObjectAccessCheck; // Only valid with mObjectHasDebugFlags
|
||||
bool mEnableCustodian;
|
||||
bool mEnableSideStack;
|
||||
bool mHasVDataExtender;
|
||||
bool mDebugAlloc;
|
||||
|
||||
bool mUseDebugBackingParams;
|
||||
|
||||
bool mWriteIR;
|
||||
bool mGenerateObj;
|
||||
|
||||
int mAllocStackCount;
|
||||
bool mExtraResolveChecks;
|
||||
int mMaxSplatRegs;
|
||||
|
||||
String mErrorString;
|
||||
|
||||
Options()
|
||||
{
|
||||
mMallocLinkName = "malloc";
|
||||
mFreeLinkName = "free";
|
||||
|
||||
mHotCompileIdx = 0;
|
||||
mForceRebuildIdx = 0;
|
||||
mCompileOnDemandKind = BfCompileOnDemandKind_AlwaysInclude;
|
||||
mMachineType = BfMachineType_x86;
|
||||
mToolsetType = BfToolsetType_Microsoft;
|
||||
mSIMDSetting = BfSIMDSetting_None;
|
||||
mHotProject = NULL;
|
||||
mDebugAlloc = false;
|
||||
mIncrementalBuild = true;
|
||||
mEmitDebugInfo = false;
|
||||
mEmitLineInfo = false;
|
||||
mNoFramePointerElim = true;
|
||||
mInitLocalVariables = false;
|
||||
mRuntimeChecks = true;
|
||||
mAllowStructByVal = false;
|
||||
mEmitDynamicCastCheck = true;
|
||||
mAllowHotSwapping = false;
|
||||
mEmitObjectAccessCheck = false;
|
||||
mObjectHasDebugFlags = false;
|
||||
mEnableRealtimeLeakCheck = false;
|
||||
mWriteIR = false;
|
||||
mGenerateObj = true;
|
||||
mEnableCustodian = false;
|
||||
mEnableSideStack = false;
|
||||
mHasVDataExtender = false;
|
||||
mUseDebugBackingParams = true;
|
||||
mAllocStackCount = 1;
|
||||
|
||||
mExtraResolveChecks = false;
|
||||
#ifdef _DEBUG
|
||||
//mExtraResolveChecks = true;
|
||||
#endif
|
||||
mMaxSplatRegs = 4;
|
||||
}
|
||||
|
||||
bool IsCodeView()
|
||||
{
|
||||
#ifdef BF_PLATFORM_WINDOWS
|
||||
return mToolsetType != BfToolsetType_GNU;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
Options mOptions;
|
||||
|
||||
enum HotTypeFlags
|
||||
{
|
||||
HotTypeFlag_None = 0,
|
||||
HotTypeFlag_UserNotUsed = 1,
|
||||
HotTypeFlag_UserUsed = 2,
|
||||
|
||||
HotTypeFlag_Heap = 4,
|
||||
HotTypeFlag_ActiveFunction = 8, // Only set for a type version mismatch
|
||||
HotTypeFlag_Delegate = 0x10, // Only set for a type version mismatch
|
||||
HotTypeFlag_FuncPtr = 0x20, // Only set for a type version mismatch
|
||||
HotTypeFlag_CanAllocate = 0x40
|
||||
};
|
||||
|
||||
enum HotResolveFlags
|
||||
{
|
||||
HotResolveFlag_None = 0,
|
||||
HotResolveFlag_HadDataChanges = 1
|
||||
};
|
||||
|
||||
struct HotReachableData
|
||||
{
|
||||
HotTypeFlags mTypeFlags;
|
||||
bool mHadNonDevirtualizedCall;
|
||||
|
||||
HotReachableData()
|
||||
{
|
||||
mTypeFlags = HotTypeFlag_None;
|
||||
mHadNonDevirtualizedCall = false;
|
||||
}
|
||||
};
|
||||
|
||||
class HotResolveData
|
||||
{
|
||||
public:
|
||||
HotResolveFlags mFlags;
|
||||
Dictionary<BfHotMethod*, HotReachableData> mReachableMethods;
|
||||
HashSet<BfHotMethod*> mActiveMethods;
|
||||
Dictionary<BfHotTypeVersion*, HotTypeFlags> mHotTypeFlags;
|
||||
Array<HotTypeFlags> mHotTypeIdFlags;
|
||||
Array<BfHotDepData*> mReasons;
|
||||
HashSet<BfHotMethod*> mDeferredThisCheckMethods;
|
||||
|
||||
~HotResolveData();
|
||||
};
|
||||
|
||||
class HotData
|
||||
{
|
||||
public:
|
||||
BfCompiler* mCompiler;
|
||||
Dictionary<String, BfHotMethod*> mMethodMap;
|
||||
Dictionary<BfHotTypeVersion*, BfHotThisType*> mThisType;
|
||||
Dictionary<BfHotTypeVersion*, BfHotAllocation*> mAllocation;
|
||||
Dictionary<BfHotMethod*, BfHotDevirtualizedMethod*> mDevirtualizedMethods;
|
||||
Dictionary<BfHotMethod*, BfHotFunctionReference*> mFuncPtrs;
|
||||
Dictionary<BfHotMethod*, BfHotVirtualDeclaration*> mVirtualDecls;
|
||||
Dictionary<BfHotMethod*, BfHotInnerMethod*> mInnerMethods;
|
||||
|
||||
public:
|
||||
~HotData();
|
||||
void ClearUnused(bool isHotCompile);
|
||||
|
||||
BfHotThisType* GetThisType(BfHotTypeVersion* hotVersion);
|
||||
BfHotAllocation* GetAllocation(BfHotTypeVersion* hotVersion);
|
||||
BfHotDevirtualizedMethod* GetDevirtualizedMethod(BfHotMethod* hotMethod);
|
||||
BfHotFunctionReference* GetFunctionReference(BfHotMethod* hotMethod);
|
||||
BfHotVirtualDeclaration* GetVirtualDeclaration(BfHotMethod* hotMethod);
|
||||
BfHotInnerMethod* GetInnerMethod(BfHotMethod* hotMethod);
|
||||
};
|
||||
|
||||
class HotState
|
||||
{
|
||||
public:
|
||||
BfProject* mHotProject;
|
||||
int mLastStringId;
|
||||
int mCommittedHotCompileIdx;
|
||||
bool mHasNewTypes;
|
||||
bool mHasNewInterfaceTypes;
|
||||
Array<BfCodeGenFileEntry> mQueuedOutFiles; // Queues up when we have failed hot compiles
|
||||
HashSet<int> mSlotDefineTypeIds;
|
||||
HashSet<int> mNewlySlottedTypeIds;
|
||||
HashSet<int> mPendingDataChanges;
|
||||
HashSet<int> mPendingFailedSlottings;
|
||||
Dictionary<String, int> mDeletedTypeNameMap;
|
||||
Val128 mVDataHashEx;
|
||||
|
||||
public:
|
||||
HotState()
|
||||
{
|
||||
mHotProject = NULL;
|
||||
mLastStringId = -1;
|
||||
mCommittedHotCompileIdx = 0;
|
||||
mHasNewTypes = false;
|
||||
mHasNewInterfaceTypes = false;
|
||||
}
|
||||
|
||||
~HotState();
|
||||
|
||||
bool HasPendingChanges(BfTypeInstance* type);
|
||||
void RemovePendingChanges(BfTypeInstance* type);
|
||||
};
|
||||
HotData* mHotData;
|
||||
HotState* mHotState;
|
||||
HotResolveData* mHotResolveData;
|
||||
|
||||
struct StringValueEntry
|
||||
{
|
||||
int mId;
|
||||
BfIRValue mStringVal;
|
||||
};
|
||||
|
||||
public:
|
||||
BfPassInstance* mPassInstance;
|
||||
FILE* mCompileLogFP;
|
||||
|
||||
BfSystem* mSystem;
|
||||
bool mIsResolveOnly;
|
||||
BfResolvePassData* mResolvePassData;
|
||||
Dictionary<String, Array<int>> mAttributeTypeOptionMap;
|
||||
int mRevision;
|
||||
bool mLastRevisionAborted;
|
||||
BfContext* mContext;
|
||||
BfCodeGen mCodeGen;
|
||||
String mOutputDirectory;
|
||||
bool mCanceling;
|
||||
bool mHadCancel;
|
||||
bool mWantsDeferMethodDecls;
|
||||
bool mInInvalidState;
|
||||
float mCompletionPct;
|
||||
int mHSPreserveIdx;
|
||||
BfModule* mLastAutocompleteModule;
|
||||
CompileState mCompileState;
|
||||
|
||||
Array<BfVDataModule*> mVDataModules;
|
||||
BfTypeDef* mArray1TypeDef;
|
||||
BfTypeDef* mArray2TypeDef;
|
||||
BfTypeDef* mArray3TypeDef;
|
||||
BfTypeDef* mArray4TypeDef;
|
||||
BfTypeDef* mSpanTypeDef;
|
||||
BfTypeDef* mAttributeTypeDef;
|
||||
BfTypeDef* mAttributeUsageAttributeTypeDef;
|
||||
BfTypeDef* mBfObjectTypeDef;
|
||||
BfTypeDef* mClassVDataTypeDef;
|
||||
BfTypeDef* mCLinkAttributeTypeDef;
|
||||
BfTypeDef* mCReprAttributeTypeDef;
|
||||
BfTypeDef* mNoDiscardAttributeTypeDef;
|
||||
BfTypeDef* mDisableObjectAccessChecksAttributeTypeDef;
|
||||
BfTypeDef* mDbgRawAllocDataTypeDef;
|
||||
BfTypeDef* mDeferredCallTypeDef;
|
||||
BfTypeDef* mDelegateTypeDef;
|
||||
BfTypeDef* mEnumTypeDef;
|
||||
BfTypeDef* mFriendAttributeTypeDef;
|
||||
BfTypeDef* mCheckedAttributeTypeDef;
|
||||
BfTypeDef* mUncheckedAttributeTypeDef;
|
||||
BfTypeDef* mFunctionTypeDef;
|
||||
BfTypeDef* mGCTypeDef;
|
||||
BfTypeDef* mGenericIEnumerableTypeDef;
|
||||
BfTypeDef* mGenericIEnumeratorTypeDef;
|
||||
BfTypeDef* mGenericIRefEnumeratorTypeDef;
|
||||
BfTypeDef* mInlineAttributeTypeDef;
|
||||
BfTypeDef* mInternalTypeDef;
|
||||
BfTypeDef* mIPrintableTypeDef;
|
||||
BfTypeDef* mLinkNameAttributeTypeDef;
|
||||
BfTypeDef* mMethodRefTypeDef;
|
||||
BfTypeDef* mNullableTypeDef;
|
||||
BfTypeDef* mOrderedAttributeTypeDef;
|
||||
BfTypeDef* mPointerTTypeDef;
|
||||
BfTypeDef* mPointerTypeDef;
|
||||
BfTypeDef* mReflectArrayType;
|
||||
BfTypeDef* mReflectFieldDataDef;
|
||||
BfTypeDef* mReflectFieldSplatDataDef;
|
||||
BfTypeDef* mReflectMethodDataDef;
|
||||
BfTypeDef* mReflectParamDataDef;
|
||||
BfTypeDef* mReflectPointerType;
|
||||
BfTypeDef* mReflectSizedArrayType;
|
||||
BfTypeDef* mReflectSpecializedGenericType;
|
||||
BfTypeDef* mReflectTypeInstanceTypeDef;
|
||||
BfTypeDef* mReflectUnspecializedGenericType;
|
||||
BfTypeDef* mSizedArrayTypeDef;
|
||||
BfTypeDef* mSkipAccessCheckAttributeTypeDef;
|
||||
BfTypeDef* mStaticInitAfterAttributeTypeDef;
|
||||
BfTypeDef* mStaticInitPriorityAttributeTypeDef;
|
||||
BfTypeDef* mStringTypeDef;
|
||||
BfTypeDef* mTestAttributeTypeDef;
|
||||
BfTypeDef* mThreadStaticAttributeTypeDef;
|
||||
BfTypeDef* mTypeTypeDef;
|
||||
BfTypeDef* mUnboundAttributeTypeDef;
|
||||
BfTypeDef* mValueTypeTypeDef;
|
||||
|
||||
int mCurTypeId;
|
||||
int mTypeInitCount;
|
||||
String mOutputPath;
|
||||
Array<BfType*> mGenericInstancePurgatory;
|
||||
Array<int> mTypeIdFreeList;
|
||||
|
||||
int mMaxInterfaceSlots;
|
||||
bool mInterfaceSlotCountChanged;
|
||||
|
||||
public:
|
||||
bool IsTypeAccessible(BfType* checkType, BfProject* curProject);
|
||||
bool IsTypeUsed(BfType* checkType, BfProject* curProject);
|
||||
bool IsModuleAccessible(BfModule* module, BfProject* curProject);
|
||||
void FixVDataHash(BfModule* bfModule);
|
||||
void CheckModuleStringRefs(BfModule* module, BfVDataModule* vdataModule, int lastModuleRevision, HashSet<int>& foundStringIds, HashSet<int>& dllNameSet, Array<BfMethodInstance*>& dllMethods, Array<BfCompiler::StringValueEntry>& stringValueEntries);
|
||||
void HashModuleVData(BfModule* module, HashContext& hash);
|
||||
BfIRFunction CreateLoadSharedLibraries(BfVDataModule* bfModule, Array<BfMethodInstance*>& dllMethods);
|
||||
void CreateVData(BfVDataModule* bfModule);
|
||||
void UpdateDependencyMap(bool deleteUnusued, bool& didWork);
|
||||
void ProcessPurgatory(bool reifiedOnly);
|
||||
bool VerifySlotNums();
|
||||
bool QuickGenerateSlotNums();
|
||||
bool SlowGenerateSlotNums();
|
||||
void GenerateSlotNums();
|
||||
void GenerateDynCastData();
|
||||
void UpdateRevisedTypes();
|
||||
void VisitAutocompleteExteriorIdentifiers();
|
||||
void VisitSourceExteriorNodes();
|
||||
void UpdateCompletion();
|
||||
bool DoWorkLoop(bool onlyReifiedTypes = false, bool onlyReifiedMethods = false);
|
||||
BfMangler::MangleKind GetMangleKind();
|
||||
|
||||
BfTypeDef* GetArrayTypeDef(int dimensions);
|
||||
void GenerateAutocompleteInfo();
|
||||
void MarkStringPool(BfModule* module);
|
||||
void ClearUnusedStringPoolEntries();
|
||||
void ClearBuildCache();
|
||||
int GetDynCastVDataCount();
|
||||
bool IsAutocomplete();
|
||||
BfAutoComplete* GetAutoComplete();
|
||||
bool IsHotCompile();
|
||||
bool IsSkippingExtraResolveChecks();
|
||||
int GetVTableMethodOffset();
|
||||
BfType* CheckSymbolReferenceTypeRef(BfModule* module, BfTypeReference* typeRef);
|
||||
void AddDepsToRebuildTypeList(BfTypeInstance* typeInst, HashSet<BfTypeInstance*>& rebuildTypeInstList);
|
||||
void CompileReified();
|
||||
void PopulateReified();
|
||||
|
||||
void HotCommit();
|
||||
void HotResolve_Start(HotResolveFlags flags);
|
||||
bool HotResolve_AddReachableMethod(BfHotMethod* hotMethod, HotTypeFlags flags, bool devirtualized, bool forceProcess = false);
|
||||
void HotResolve_AddReachableMethod(const StringImpl& methodName);
|
||||
void HotResolve_AddActiveMethod(BfHotMethod* hotMethod);
|
||||
void HotResolve_AddActiveMethod(const StringImpl& methodName);
|
||||
void HotResolve_AddDelegateMethod(const StringImpl& methodName);
|
||||
void HotResolve_ReportType(BfHotTypeVersion* hotTypeVersion, HotTypeFlags flags, BfHotDepData* reason);
|
||||
void HotResolve_ReportType(int typeId, HotTypeFlags flags);
|
||||
String HotResolve_Finish();
|
||||
void ClearOldHotData();
|
||||
|
||||
public:
|
||||
BfCompiler(BfSystem* bfSystem, bool isResolveOnly);
|
||||
~BfCompiler();
|
||||
|
||||
bool Compile(const StringImpl& outputPath);
|
||||
bool DoCompile(const StringImpl& outputPath);
|
||||
void ClearResults();
|
||||
void ProcessAutocompleteTempType();
|
||||
void GetSymbolReferences();
|
||||
void Cancel();
|
||||
String GetTypeDefList();
|
||||
String GetTypeDefMatches(const StringImpl& searchSrc);
|
||||
String GetTypeDefInfo(const StringImpl& typeName);
|
||||
|
||||
void CompileLog(const char* fmt ...);
|
||||
void ReportMemory(MemReporter* memReporter);
|
||||
};
|
||||
|
||||
NS_BF_END
|
||||
|
366
IDEHelper/Compiler/BfConstResolver.cpp
Normal file
366
IDEHelper/Compiler/BfConstResolver.cpp
Normal file
|
@ -0,0 +1,366 @@
|
|||
#pragma warning(push)
|
||||
#pragma warning(disable:4800)
|
||||
#pragma warning(disable:4244)
|
||||
#pragma warning(disable:4141)
|
||||
#pragma warning(disable:4624)
|
||||
#pragma warning(disable:4146)
|
||||
#pragma warning(disable:4267)
|
||||
#pragma warning(disable:4291)
|
||||
|
||||
#include "BfCompiler.h"
|
||||
#include "BfConstResolver.h"
|
||||
#include "BfAutoComplete.h"
|
||||
#include "BfResolvePass.h"
|
||||
#include "llvm/IR/GlobalVariable.h"
|
||||
#include "BfExprEvaluator.h"
|
||||
|
||||
#pragma warning(pop)
|
||||
|
||||
USING_NS_BF;
|
||||
using namespace llvm;
|
||||
|
||||
bool BfConstResolver::CheckAllowValue(const BfTypedValue& typedValue, BfAstNode* refNode)
|
||||
{
|
||||
if (typedValue.mValue.IsConst())
|
||||
return true;
|
||||
|
||||
mModule->Fail("Expression does not evaluate to a constant value", refNode);
|
||||
return false;
|
||||
}
|
||||
|
||||
BfConstResolver::BfConstResolver(BfModule* bfModule) : BfExprEvaluator(bfModule)
|
||||
{
|
||||
mIsInvalidConstExpr = false;
|
||||
mAllowGenericConstValue = false;
|
||||
}
|
||||
|
||||
BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfConstResolveFlags flags)
|
||||
{
|
||||
bool explicitCast = (flags & BfConstResolveFlag_ExplicitCast) != 0;
|
||||
bool noCast = (flags & BfConstResolveFlag_NoCast) != 0;
|
||||
bool allowSoftFail = (flags & BfConstResolveFlag_AllowSoftFail) != 0;
|
||||
bool wantIgnoreWrites = mModule->mBfIRBuilder->mIgnoreWrites;
|
||||
/*if (BfNodeDynCastExact<BfTypeOfExpression>(expr) != NULL)
|
||||
{
|
||||
// Some specific expressions should be allowed to do writes like creating global variables
|
||||
}
|
||||
else*/
|
||||
{
|
||||
wantIgnoreWrites = true;
|
||||
}
|
||||
|
||||
SetAndRestoreValue<bool> ignoreWrites(mModule->mBfIRBuilder->mIgnoreWrites, wantIgnoreWrites);
|
||||
|
||||
auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
|
||||
|
||||
mNoBind = true;
|
||||
if (wantType != NULL)
|
||||
mExpectingType = wantType;
|
||||
VisitChildNoRef(expr);
|
||||
mResult = GetResult();
|
||||
if (mResult)
|
||||
mResult = mModule->LoadValue(mResult);
|
||||
if ((mResult) && (wantType != NULL))
|
||||
{
|
||||
auto typeInst = mResult.mType->ToTypeInstance();
|
||||
if ((typeInst != NULL) && (typeInst->mTypeDef == mModule->mCompiler->mStringTypeDef))
|
||||
{
|
||||
BfType* toType = wantType;
|
||||
if (toType == NULL)
|
||||
toType = mResult.mType;
|
||||
|
||||
if ((mResult.mValue.IsConst()) &&
|
||||
(((toType->IsPointer()) && (toType->GetUnderlyingType() == mModule->GetPrimitiveType(BfTypeCode_Char8))) ||
|
||||
(toType == mResult.mType)))
|
||||
{
|
||||
auto constant = mModule->mBfIRBuilder->GetConstant(mResult.mValue);
|
||||
if (constant->mTypeCode == BfTypeCode_NullPtr)
|
||||
{
|
||||
return mModule->GetDefaultTypedValue(toType);
|
||||
}
|
||||
else
|
||||
{
|
||||
int stringId = mModule->GetStringPoolIdx(mResult.mValue);
|
||||
BF_ASSERT(stringId >= 0);
|
||||
return BfTypedValue(mModule->GetConstValue(stringId), toType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (noCast)
|
||||
{
|
||||
//
|
||||
}
|
||||
else if (allowSoftFail)
|
||||
{
|
||||
SetAndRestoreValue<bool> prevIgnoreFail(mModule->mIgnoreErrors, true);
|
||||
auto convValue = mModule->Cast(expr, mResult, wantType, explicitCast ? BfCastFlags_Explicit : BfCastFlags_None);
|
||||
if (convValue)
|
||||
mResult = convValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
mResult = mModule->Cast(expr, mResult, wantType, (BfCastFlags)(BfCastFlags_NoConversionOperator | (explicitCast ? BfCastFlags_Explicit : BfCastFlags_None)));
|
||||
}
|
||||
}
|
||||
|
||||
if (mResult.mKind == BfTypedValueKind_GenericConstValue)
|
||||
{
|
||||
if (mAllowGenericConstValue)
|
||||
return mResult;
|
||||
|
||||
auto genericParamDef = mModule->GetGenericParamInstance((BfGenericParamType*)mResult.mType);
|
||||
if ((genericParamDef->mGenericParamFlags & BfGenericParamFlag_Const) != 0)
|
||||
{
|
||||
auto genericTypeConstraint = genericParamDef->mTypeConstraint;
|
||||
if (genericTypeConstraint != NULL)
|
||||
{
|
||||
auto primType = genericTypeConstraint->ToPrimitiveType();
|
||||
if (primType != NULL)
|
||||
{
|
||||
BfTypedValue result;
|
||||
result.mKind = BfTypedValueKind_Value;
|
||||
result.mType = genericTypeConstraint;
|
||||
result.mValue = mModule->mBfIRBuilder->GetUndefConstValue(primType->mTypeDef->mTypeCode);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BF_FATAL("Error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mResult)
|
||||
{
|
||||
bool isConst = mResult.mValue.IsConst();
|
||||
|
||||
if (isConst)
|
||||
{
|
||||
auto constant = mModule->mBfIRBuilder->GetConstant(mResult.mValue);
|
||||
if (constant->mConstType == BfConstType_GlobalVar)
|
||||
isConst = false;
|
||||
}
|
||||
|
||||
if (!isConst)
|
||||
{
|
||||
mModule->Fail("Expression does not evaluate to a constant value", expr);
|
||||
|
||||
if (wantType != NULL)
|
||||
mResult = mModule->GetDefaultTypedValue(wantType);
|
||||
else
|
||||
mResult = BfTypedValue();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wantType != NULL)
|
||||
mResult = mModule->GetDefaultTypedValue(wantType);
|
||||
}
|
||||
|
||||
if (prevInsertBlock)
|
||||
mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
|
||||
/*ignoreWrites.Restore();
|
||||
if ((!mModule->mBfIRBuilder->mIgnoreWrites) && (prevInsertBlock))
|
||||
{
|
||||
BF_ASSERT(!prevInsertBlock.IsFake());
|
||||
mModule->mBfIRBuilder->SetInsertPoint(prevInsertBlock);
|
||||
}*/
|
||||
|
||||
mModule->FixIntUnknown(mResult);
|
||||
|
||||
return mResult;
|
||||
}
|
||||
|
||||
bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatcher* methodMatcher, Array<BfIRValue>& llvmArgs)
|
||||
{
|
||||
int argIdx = 0;
|
||||
int paramIdx = 0;
|
||||
|
||||
int extendedParamIdx = 0;
|
||||
|
||||
llvm::SmallVector<BfIRValue, 4> expandedParamsConstValues;
|
||||
BfType* expandedParamsElementType = NULL;
|
||||
|
||||
// We don't do GetMethodInstance in mModule, because our module may not have init finished yet
|
||||
//auto targetModule = methodMatcher->mBestMethodTypeInstance->mModule;
|
||||
auto targetModule = mModule->mContext->mUnreifiedModule;
|
||||
auto moduleMethodInstance = targetModule->GetMethodInstance(methodMatcher->mBestMethodTypeInstance, methodMatcher->mBestMethodDef, methodMatcher->mBestMethodGenericArguments);
|
||||
auto methodInstance = moduleMethodInstance.mMethodInstance;
|
||||
|
||||
if (methodInstance->mReturnType == NULL)
|
||||
{
|
||||
mModule->AssertErrorState();
|
||||
return false;
|
||||
}
|
||||
|
||||
auto methodDef = methodMatcher->mBestMethodDef;
|
||||
auto& arguments = methodMatcher->mArguments;
|
||||
|
||||
mModule->AddDependency(methodInstance->mReturnType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
|
||||
for (int paramIdx = 0; paramIdx < methodInstance->GetParamCount(); paramIdx++)
|
||||
{
|
||||
auto paramType = methodInstance->GetParamType(paramIdx);
|
||||
mModule->AddDependency(paramType, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_LocalUsage);
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (paramIdx >= (int)methodInstance->GetParamCount())
|
||||
{
|
||||
if (argIdx < (int)arguments.size())
|
||||
{
|
||||
BfAstNode* errorRef = arguments[methodInstance->GetParamCount()].mExpression;
|
||||
if (errorRef->GetSourceData() == NULL)
|
||||
errorRef = targetSrc;
|
||||
mModule->Fail(StrFormat("Too many arguments. Expected %d fewer.", (int)arguments.size() - methodInstance->GetParamCount()), errorRef);
|
||||
if (methodInstance->mMethodDef->mMethodDeclaration != NULL)
|
||||
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->mMethodDeclaration);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
BfType* wantType = NULL;
|
||||
if (expandedParamsElementType != NULL)
|
||||
{
|
||||
wantType = expandedParamsElementType;
|
||||
}
|
||||
else
|
||||
{
|
||||
wantType = methodInstance->GetParamType(paramIdx);
|
||||
|
||||
if (methodInstance->GetParamKind(paramIdx) == BfParamKind_Params)
|
||||
{
|
||||
//TODO: Check to see if it's a direct array pass
|
||||
|
||||
bool isDirectPass = false;
|
||||
if (argIdx < (int)arguments.size())
|
||||
{
|
||||
if (!arguments[argIdx].mTypedValue.mValue)
|
||||
return false;
|
||||
if (mModule->CanImplicitlyCast(arguments[argIdx].mTypedValue, wantType))
|
||||
isDirectPass = true;
|
||||
}
|
||||
|
||||
if (!isDirectPass)
|
||||
{
|
||||
BfArrayType* arrayType = (BfArrayType*)wantType;
|
||||
if (arrayType->IsIncomplete())
|
||||
mModule->PopulateType(arrayType, BfPopulateType_DataAndMethods);
|
||||
expandedParamsElementType = arrayType->mTypeGenericArguments[0];
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BfAstNode* argExpr = NULL;
|
||||
if (argIdx < (int)arguments.size())
|
||||
{
|
||||
argExpr = arguments[argIdx].mExpression;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (expandedParamsElementType != NULL)
|
||||
break;
|
||||
|
||||
if ((argIdx >= (int)methodInstance->mDefaultValues.size()) || (!methodInstance->mDefaultValues[argIdx]))
|
||||
{
|
||||
BfAstNode* refNode = targetSrc;
|
||||
if (arguments.size() > 0)
|
||||
refNode = arguments.back().mExpression;
|
||||
|
||||
BfAstNode* prevNode = NULL;
|
||||
#ifdef BF_AST_HAS_PARENT_MEMBER
|
||||
if (auto attributeDirective = BfNodeDynCast<BfAttributeDirective>(targetSrc->mParent))
|
||||
{
|
||||
BF_ASSERT(mModule->mParentNodeEntry->mNode == attributeDirective);
|
||||
}
|
||||
#endif
|
||||
if (mModule->mParentNodeEntry != NULL)
|
||||
{
|
||||
if (auto attributeDirective = BfNodeDynCast<BfAttributeDirective>(mModule->mParentNodeEntry->mNode))
|
||||
{
|
||||
if (attributeDirective->mCommas.size() > 0)
|
||||
prevNode = attributeDirective->mCommas.back();
|
||||
else
|
||||
prevNode = attributeDirective->mCtorOpenParen;
|
||||
if (attributeDirective->mCtorCloseParen != NULL)
|
||||
refNode = attributeDirective->mCtorCloseParen;
|
||||
}
|
||||
}
|
||||
|
||||
auto autoComplete = GetAutoComplete();
|
||||
if (autoComplete != NULL)
|
||||
{
|
||||
if (prevNode != NULL)
|
||||
{
|
||||
autoComplete->CheckEmptyStart(prevNode, wantType);
|
||||
}
|
||||
}
|
||||
|
||||
mModule->Fail(StrFormat("Not enough parameters specified. Expected %d fewer.", methodInstance->GetParamCount() - (int)arguments.size()), refNode);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto foreignDefaultVal = methodInstance->mDefaultValues[argIdx];
|
||||
auto foreignConst = methodInstance->GetOwner()->mConstHolder->GetConstant(methodInstance->mDefaultValues[argIdx]);
|
||||
auto constVal = mModule->ConstantToCurrent(foreignConst, methodInstance->GetOwner()->mConstHolder, wantType);
|
||||
llvmArgs.push_back(constVal);
|
||||
argIdx++;
|
||||
paramIdx++;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto argValue = arguments[argIdx].mTypedValue;
|
||||
|
||||
auto& arg = arguments[argIdx];
|
||||
if ((arg.mArgFlags & BfArgFlag_DeferredEval) != 0)
|
||||
{
|
||||
mExpectingType = arg.mExpectedType;
|
||||
|
||||
if (auto expr = BfNodeDynCast<BfExpression>(argExpr))
|
||||
argValue = Resolve(expr, mExpectingType);
|
||||
arg.mArgFlags = BfArgFlag_None;
|
||||
}
|
||||
|
||||
|
||||
if (!argValue)
|
||||
return BfTypedValue();
|
||||
|
||||
if (argExpr != NULL)
|
||||
{
|
||||
argValue = mModule->Cast(argExpr, argValue, wantType);
|
||||
if (!argValue)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!argValue)
|
||||
{
|
||||
mModule->Fail("Invalid expression type", argExpr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (expandedParamsElementType != NULL)
|
||||
{
|
||||
expandedParamsConstValues.push_back(argValue.mValue);
|
||||
extendedParamIdx++;
|
||||
}
|
||||
else
|
||||
{
|
||||
llvmArgs.push_back(argValue.mValue);
|
||||
paramIdx++;
|
||||
}
|
||||
argIdx++;
|
||||
}
|
||||
|
||||
if (expandedParamsElementType != NULL)
|
||||
{
|
||||
auto arrayType = mModule->mBfIRBuilder->GetSizedArrayType(mModule->mBfIRBuilder->MapType(expandedParamsElementType), (int)expandedParamsConstValues.size());
|
||||
auto constArray = mModule->mBfIRBuilder->CreateConstArray(arrayType, expandedParamsConstValues);
|
||||
llvmArgs.push_back(constArray);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
36
IDEHelper/Compiler/BfConstResolver.h
Normal file
36
IDEHelper/Compiler/BfConstResolver.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
#include "BeefySysLib/Common.h"
|
||||
#include "BfAst.h"
|
||||
#include "BfSystem.h"
|
||||
#include "BfCompiler.h"
|
||||
#include "BfExprEvaluator.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
class BfModule;
|
||||
class BfMethodMatcher;
|
||||
|
||||
enum BfConstResolveFlags
|
||||
{
|
||||
BfConstResolveFlag_None = 0,
|
||||
BfConstResolveFlag_ExplicitCast = 1,
|
||||
BfConstResolveFlag_NoCast = 2,
|
||||
BfConstResolveFlag_AllowSoftFail = 4,
|
||||
};
|
||||
|
||||
class BfConstResolver : public BfExprEvaluator
|
||||
{
|
||||
public:
|
||||
bool mIsInvalidConstExpr;
|
||||
bool mAllowGenericConstValue;
|
||||
|
||||
public:
|
||||
virtual bool CheckAllowValue(const BfTypedValue& typedValue, BfAstNode* refNode) override;
|
||||
|
||||
public:
|
||||
BfConstResolver(BfModule* bfModule);
|
||||
|
||||
BfTypedValue Resolve(BfExpression* expr, BfType* wantType = NULL, BfConstResolveFlags flags = BfConstResolveFlag_None);
|
||||
bool PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatcher* methodMatcher, Array<BfIRValue>& llvmArgs);
|
||||
};
|
||||
|
||||
NS_BF_END
|
2638
IDEHelper/Compiler/BfContext.cpp
Normal file
2638
IDEHelper/Compiler/BfContext.cpp
Normal file
File diff suppressed because it is too large
Load diff
402
IDEHelper/Compiler/BfContext.h
Normal file
402
IDEHelper/Compiler/BfContext.h
Normal file
|
@ -0,0 +1,402 @@
|
|||
#pragma once
|
||||
|
||||
#include "BfModule.h"
|
||||
#include "BeefySysLib/util/Deque.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
class BfWorkListEntry
|
||||
{
|
||||
public:
|
||||
BfType* mType;
|
||||
BfModule* mFromModule;
|
||||
int mRevision;
|
||||
int mSignatureRevision;
|
||||
int mFromModuleRevision;
|
||||
int mFromModuleRebuildIdx;
|
||||
int mReqId;
|
||||
static int sCurReqId;
|
||||
|
||||
public:
|
||||
BfWorkListEntry()
|
||||
{
|
||||
mType = NULL;
|
||||
mFromModule = NULL;
|
||||
mRevision = -1;
|
||||
mSignatureRevision = -1;
|
||||
mFromModuleRevision = -1;
|
||||
mFromModuleRebuildIdx = -1;
|
||||
mReqId = ++sCurReqId;
|
||||
}
|
||||
};
|
||||
|
||||
class BfTypeProcessRequest : public BfWorkListEntry
|
||||
{
|
||||
public:
|
||||
bool mRebuildType;
|
||||
|
||||
BfTypeProcessRequest()
|
||||
{
|
||||
mRebuildType = false;
|
||||
}
|
||||
};
|
||||
|
||||
class BfMethodSpecializationRequest : public BfWorkListEntry
|
||||
{
|
||||
public:
|
||||
BfMethodDef* mMethodDef;
|
||||
BfTypeVector mMethodGenericArguments;
|
||||
BfGetMethodInstanceFlags mFlags;
|
||||
|
||||
public:
|
||||
BfMethodSpecializationRequest()
|
||||
{
|
||||
mMethodDef = NULL;
|
||||
mFlags = BfGetMethodInstanceFlag_None;
|
||||
}
|
||||
};
|
||||
|
||||
class BfMethodProcessRequest : public BfWorkListEntry
|
||||
{
|
||||
public:
|
||||
BfMethodInstance* mMethodInstance;
|
||||
|
||||
BfMethodProcessRequest()
|
||||
{
|
||||
mMethodInstance = NULL;
|
||||
}
|
||||
|
||||
~BfMethodProcessRequest()
|
||||
{
|
||||
Disable();
|
||||
}
|
||||
|
||||
void Disable()
|
||||
{
|
||||
if (mMethodInstance != NULL)
|
||||
{
|
||||
BF_ASSERT(mMethodInstance->mMethodProcessRequest == this);
|
||||
mMethodInstance->mMethodProcessRequest = NULL;
|
||||
mMethodInstance = NULL;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class BfInlineMethodRequest : public BfMethodProcessRequest
|
||||
{
|
||||
public:
|
||||
BfIRFunction mFunc;
|
||||
|
||||
~BfInlineMethodRequest()
|
||||
{
|
||||
mMethodInstance = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
struct BfStringPoolEntry
|
||||
{
|
||||
String mString;
|
||||
int mLastUsedRevision;
|
||||
int mFirstUsedRevision;
|
||||
};
|
||||
|
||||
class BfGlobalContainerEntry
|
||||
{
|
||||
public:
|
||||
BfTypeDef* mTypeDef;
|
||||
BfTypeInstance* mTypeInst;
|
||||
};
|
||||
|
||||
class BfTypeState
|
||||
{
|
||||
public:
|
||||
BfTypeState* mPrevState;
|
||||
|
||||
BfTypeInstance* mTypeInstance;
|
||||
BfTypeDef* mGlobalContainerCurUserTypeDef;
|
||||
Array<BfGlobalContainerEntry> mGlobalContainers; // All global containers that are visible
|
||||
|
||||
BfPopulateType mPopulateType;
|
||||
BfTypeReference* mCurBaseTypeRef;
|
||||
BfTypeReference* mCurAttributeTypeRef;
|
||||
BfFieldDef* mCurFieldDef;
|
||||
BfTypeDef* mCurTypeDef;
|
||||
bool mBuildingGenericParams;
|
||||
|
||||
public:
|
||||
BfTypeState()
|
||||
{
|
||||
mPrevState = NULL;
|
||||
mTypeInstance = NULL;
|
||||
mGlobalContainerCurUserTypeDef = NULL;
|
||||
|
||||
mPopulateType = BfPopulateType_Identity;
|
||||
mCurBaseTypeRef = NULL;
|
||||
mCurFieldDef = NULL;
|
||||
mCurAttributeTypeRef = NULL;
|
||||
mCurTypeDef = NULL;
|
||||
mBuildingGenericParams = false;
|
||||
}
|
||||
|
||||
BfTypeState(BfTypeInstance* typeInstance, BfTypeState* prevState = NULL)
|
||||
{
|
||||
mPrevState = prevState;
|
||||
mTypeInstance = typeInstance;
|
||||
mGlobalContainerCurUserTypeDef = NULL;
|
||||
|
||||
mPopulateType = BfPopulateType_Declaration;
|
||||
mCurBaseTypeRef = NULL;
|
||||
mCurFieldDef = NULL;
|
||||
mCurAttributeTypeRef = NULL;
|
||||
mCurTypeDef = NULL;
|
||||
mBuildingGenericParams = false;
|
||||
}
|
||||
};
|
||||
|
||||
class BfSavedTypeData
|
||||
{
|
||||
public:
|
||||
BfHotTypeData* mHotTypeData;
|
||||
int mTypeId;
|
||||
|
||||
public:
|
||||
~BfSavedTypeData()
|
||||
{
|
||||
delete mHotTypeData;
|
||||
}
|
||||
};
|
||||
|
||||
struct SpecializedErrorData
|
||||
{
|
||||
// We need to store errors during type specialization and method specialization,
|
||||
// because if the type is deleted we need to clear the errors
|
||||
BfTypeInstance* mRefType;
|
||||
BfModule* mModule;
|
||||
BfMethodInstance* mMethodInstance;
|
||||
BfError* mError;
|
||||
|
||||
SpecializedErrorData()
|
||||
{
|
||||
mRefType = NULL;
|
||||
mModule = NULL;
|
||||
mMethodInstance = NULL;
|
||||
mError = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
struct BfCaseInsensitiveStringHash
|
||||
{
|
||||
size_t operator()(const StringImpl& str) const
|
||||
{
|
||||
int curHash = 0;
|
||||
for (int i = 0; i < (int)str.length(); i++)
|
||||
curHash = ((curHash ^ (int)(intptr)toupper(str[i])) << 5) - curHash;
|
||||
return curHash;
|
||||
}
|
||||
};
|
||||
|
||||
struct BfCaseInsensitiveStringEquals
|
||||
{
|
||||
bool operator()(const StringImpl& lhs, const StringImpl& rhs) const
|
||||
{
|
||||
if (lhs.length() != rhs.length())
|
||||
return false;
|
||||
return _stricmp(lhs.c_str(), rhs.c_str()) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class WorkQueue : public Deque<T*>
|
||||
{
|
||||
public:
|
||||
BumpAllocator mWorkAlloc;
|
||||
|
||||
int RemoveAt(int idx)
|
||||
{
|
||||
if (idx == 0)
|
||||
{
|
||||
T*& ref = (*this)[idx];
|
||||
if (ref != NULL)
|
||||
(*ref).~T();
|
||||
Deque<T*>::RemoveAt(0);
|
||||
if (this->mSize == 0)
|
||||
{
|
||||
mWorkAlloc.Clear();
|
||||
this->mOffset = 0;
|
||||
}
|
||||
|
||||
return idx - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
T*& ref = (*this)[idx];
|
||||
if (ref != NULL)
|
||||
{
|
||||
(*ref).~T();
|
||||
ref = NULL;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
Deque<T*>::Clear();
|
||||
mWorkAlloc.Clear();
|
||||
}
|
||||
|
||||
T* Alloc()
|
||||
{
|
||||
T* item = mWorkAlloc.Alloc<T>();
|
||||
this->Add(item);
|
||||
return item;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class PtrWorkQueue : public Deque<T>
|
||||
{
|
||||
public:
|
||||
int RemoveAt(int idx)
|
||||
{
|
||||
if (idx == 0)
|
||||
{
|
||||
Deque<T>::RemoveAt(0);
|
||||
return idx - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*this)[idx] = NULL;
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class BfContext
|
||||
{
|
||||
public:
|
||||
CritSect mCritSect;
|
||||
bool mDeleting;
|
||||
|
||||
BfTypeState* mCurTypeState;
|
||||
bool mResolvingVarField;
|
||||
int mMappedObjectRevision;
|
||||
|
||||
BfSystem* mSystem;
|
||||
BfCompiler* mCompiler;
|
||||
|
||||
bool mLockModules;
|
||||
BfModule* mScratchModule;
|
||||
BfModule* mUnreifiedModule;
|
||||
HashSet<String> mUsedModuleNames;
|
||||
Array<BfModule*> mModules;
|
||||
Array<BfModule*> mDeletingModules;
|
||||
HashSet<BfTypeInstance*> mFailTypes; // All types handled after a failure need to be rebuild on subsequent compile
|
||||
HashSet<BfTypeInstance*> mReferencedIFaceSlots;
|
||||
|
||||
BfMethodInstance* mValueTypeDeinitSentinel;
|
||||
|
||||
Array<BfAstNode*> mTempNodes;
|
||||
BfResolvedTypeSet mResolvedTypes;
|
||||
Array<BfType*> mTypes; // Can contain NULLs for deleted types
|
||||
Array<BfFieldInstance*> mFieldResolveReentrys; // For detecting 'var' field circular refs
|
||||
Dictionary<String, BfSavedTypeData*> mSavedTypeDataMap;
|
||||
Array<BfSavedTypeData*> mSavedTypeData;
|
||||
|
||||
BfTypeInstance* mBfTypeType;
|
||||
BfTypeInstance* mBfObjectType;
|
||||
BfPointerType* mBfClassVDataPtrType;
|
||||
|
||||
PtrWorkQueue<BfModule*> mReifyModuleWorkList;
|
||||
WorkQueue<BfMethodProcessRequest> mMethodWorkList;
|
||||
WorkQueue<BfInlineMethodRequest> mInlineMethodWorkList;
|
||||
WorkQueue<BfTypeProcessRequest> mPopulateTypeWorkList;
|
||||
WorkQueue<BfMethodSpecializationRequest> mMethodSpecializationWorkList;
|
||||
PtrWorkQueue<BfModule*> mFinishedSlotAwaitModuleWorkList;
|
||||
PtrWorkQueue<BfModule*> mFinishedModuleWorkList;
|
||||
|
||||
Array<BfGenericParamType*> mGenericParamTypes[3];
|
||||
|
||||
Array<BfType*> mTypeGraveyard;
|
||||
Array<BfTypeDef*> mTypeDefGraveyard;
|
||||
Array<BfLocalMethod*> mLocalMethodGraveyard;
|
||||
|
||||
Dictionary<String, int> mStringObjectPool;
|
||||
Dictionary<int, BfStringPoolEntry> mStringObjectIdMap;
|
||||
int mCurStringObjectPoolId;
|
||||
|
||||
HashSet<BfTypeInstance*> mQueuedSpecializedMethodRebuildTypes;
|
||||
|
||||
BfAllocPool<BfPointerType> mPointerTypePool;
|
||||
BfAllocPool<BfArrayType> mArrayTypePool;
|
||||
BfAllocPool<BfSizedArrayType> mSizedArrayTypePool;
|
||||
BfAllocPool<BfUnknownSizedArrayType> mUnknownSizedArrayTypePool;
|
||||
BfAllocPool<BfBoxedType> mBoxedTypePool;
|
||||
BfAllocPool<BfTupleType> mTupleTypePool;
|
||||
BfAllocPool<BfRefType> mRefTypePool;
|
||||
BfAllocPool<BfRetTypeType> mRetTypeTypePool;
|
||||
BfAllocPool<BfGenericTypeInstance> mGenericTypeInstancePool;
|
||||
BfAllocPool<BfGenericTypeAliasType> mGenericTypeAliasPool;
|
||||
BfAllocPool<BfArrayType> mArrayTypeInstancePool;
|
||||
BfAllocPool<BfGenericParamType> mGenericParamTypePool;
|
||||
BfAllocPool<BfDirectTypeDefReference> mTypeDefTypeRefPool;
|
||||
BfAllocPool<BfDirectStrTypeReference> mNamedTypeRefPool;
|
||||
BfAllocPool<BfGenericInstanceTypeRef> mGenericTypeRefPool;
|
||||
BfAllocPool<BfConcreteInterfaceType> mConcreteInterfaceTypePool;
|
||||
BfAllocPool<BfConstExprValueType> mConstExprValueTypePool;
|
||||
BfPrimitiveType* mPrimitiveTypes[BfTypeCode_Length];
|
||||
BfPrimitiveType* mPrimitiveStructTypes[BfTypeCode_Length];
|
||||
|
||||
public:
|
||||
void AssignModule(BfType* type);
|
||||
void HandleTypeWorkItem(BfType* type);
|
||||
void EnsureHotMangledVirtualMethodName(BfMethodInstance* methodInstance);
|
||||
void EnsureHotMangledVirtualMethodNames();
|
||||
void PopulateHotTypeDataVTable(BfTypeInstance* typeInstance);
|
||||
void DeleteType(BfType* type, bool deferDepRebuilds = false);
|
||||
void UpdateAfterDeletingTypes();
|
||||
void VerifyTypeLookups(BfTypeInstance* typeInst);
|
||||
void GenerateModuleName_TypeInst(BfTypeInstance* typeInst, String& name);
|
||||
void GenerateModuleName_Type(BfType* type, String& name);
|
||||
String GenerateModuleName(BfTypeInstance* typeInst);
|
||||
bool IsSentinelMethod(BfMethodInstance* methodInstance);
|
||||
void SaveDeletingType(BfType* type);
|
||||
BfType* FindType(const StringImpl& typeName);
|
||||
String TypeIdToString(int typeId);
|
||||
BfHotTypeData* GetHotTypeData(int typeId);
|
||||
|
||||
public:
|
||||
BfContext(BfCompiler* compiler);
|
||||
~BfContext();
|
||||
|
||||
void ReportMemory(MemReporter* memReporter);
|
||||
void ProcessMethod(BfMethodInstance* methodInstance);
|
||||
int GetStringLiteralId(const StringImpl& str);
|
||||
bool IsCancellingAndYield();
|
||||
void QueueFinishModule(BfModule * module);
|
||||
void CancelWorkItems();
|
||||
bool ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods);
|
||||
void HandleChangedTypeDef(BfTypeDef* typeDef, bool isAutoCompleteTempType = false);
|
||||
void PreUpdateRevisedTypes();
|
||||
void UpdateRevisedTypes();
|
||||
void VerifyTypeLookups();
|
||||
void QueueMethodSpecializations(BfTypeInstance* typeInst, bool checkSpecializedMethodRebuildFlag);
|
||||
void MarkAsReferenced(BfDependedType* depType);
|
||||
void RemoveInvalidFailTypes();
|
||||
void RemoveInvalidWorkItems();
|
||||
BfType* FindTypeById(int typeId);
|
||||
void AddTypeToWorkList(BfType* type);
|
||||
void RebuildType(BfType* type, bool deleteOnDemandTypes = true, bool rebuildModule = true, bool placeSpecializiedInPurgatory = true);
|
||||
void RebuildDependentTypes(BfDependedType* dType);
|
||||
void TypeDataChanged(BfDependedType* dType, bool isNonStaticDataChange);
|
||||
void TypeMethodSignaturesChanged(BfTypeInstance* typeInst);
|
||||
void TypeInlineMethodInternalsChanged(BfTypeInstance* typeInst);
|
||||
void CheckSpecializedErrorData();
|
||||
void TryUnreifyModules();
|
||||
void MarkUsedModules(BfProject* project, BfModule* module);
|
||||
void RemapObject();
|
||||
void Finish();
|
||||
void Cleanup();
|
||||
};
|
||||
|
||||
NS_BF_END
|
2084
IDEHelper/Compiler/BfDefBuilder.cpp
Normal file
2084
IDEHelper/Compiler/BfDefBuilder.cpp
Normal file
File diff suppressed because it is too large
Load diff
66
IDEHelper/Compiler/BfDefBuilder.h
Normal file
66
IDEHelper/Compiler/BfDefBuilder.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
|
||||
#include "BeefySysLib/Common.h"
|
||||
#include "BfAst.h"
|
||||
#include "BfSystem.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
// This is the first pass through our ASTs, builds up Def structures in BfSystem
|
||||
// so when we go to compile we'll be able to resolve references
|
||||
|
||||
class BfResolvePassData;
|
||||
|
||||
class BfDefBuilder : public BfStructuralVisitor
|
||||
{
|
||||
public:
|
||||
BfSource* mCurSource;
|
||||
BfSystem* mSystem;
|
||||
BfPassInstance* mPassInstance;
|
||||
BfTypeDef* mCurTypeDef;
|
||||
BfTypeDef* mCurActualTypeDef;
|
||||
bool mFullRefresh;
|
||||
BfResolvePassData* mResolvePassData;
|
||||
BfAtomComposite mNamespace;
|
||||
Array<BfAtomComposite> mNamespaceSearch;
|
||||
Array<BfTypeReference*> mStaticSearch;
|
||||
HashContext* mFullHashCtx;
|
||||
HashContext* mSignatureHashCtx;
|
||||
|
||||
public:
|
||||
void ParseGenericParams(BfGenericParamsDeclaration* genericParamsDecl, BfGenericConstraintsDeclaration* genericConstraints, Array<BfGenericParamDef*>& genericParams, int outerGenericSize);
|
||||
BfProtection GetProtection(BfTokenNode* protectionToken);
|
||||
bool WantsNode(BfAstNode* wholeNode, BfAstNode* startNode = NULL, int addLen = 0);
|
||||
//static BfNamedTypeReference* AllocTypeReference(BfSource* bfSource, const StringImpl& typeName);
|
||||
//static BfResolvedTypeReference* AllocTypeReference(BfSource* bfSource, BfType* type);
|
||||
static BfFieldDef* AddField(BfTypeDef* typeDef, BfTypeReference* typeRef, const StringImpl& name);
|
||||
static BfMethodDef* AddMethod(BfTypeDef* typeDef, BfMethodType methodType, BfProtection protection, bool isStatic, const StringImpl& name);
|
||||
static BfMethodDef* AddDtor(BfTypeDef* typeDef);
|
||||
static void AddDynamicCastMethods(BfTypeDef* typeDef);
|
||||
void AddParam(BfMethodDef* methodDef, BfTypeReference* typeRef, const StringImpl& paramName);
|
||||
void FinishTypeDef(bool wantsToString);
|
||||
void ParseAttributes(BfAttributeDirective* attributes, BfMethodDef* methodDef);
|
||||
void ParseAttributes(BfAttributeDirective* attributes, BfTypeDef* typeDef);
|
||||
BfMethodDef* CreateMethodDef(BfMethodDeclaration* methodDecl, BfMethodDef* outerMethodDef = NULL);
|
||||
|
||||
public:
|
||||
BfDefBuilder(BfSystem* bfSystem);
|
||||
~BfDefBuilder();
|
||||
|
||||
void Process(BfPassInstance* passInstance, BfSource* bfSource, bool fullRefresh);
|
||||
void RemoveDefsFrom(BfSource* bfSource);
|
||||
|
||||
virtual void Visit(BfIdentifierNode* identifier) override;
|
||||
virtual void Visit(BfMethodDeclaration* methodDeclaration) override;
|
||||
virtual void Visit(BfConstructorDeclaration* ctorDeclaration) override;
|
||||
virtual void Visit(BfPropertyDeclaration* propertyDeclaration) override;
|
||||
virtual void Visit(BfFieldDeclaration* fieldDeclaration) override;
|
||||
virtual void Visit(BfEnumCaseDeclaration* enumCaseDeclaration) override;
|
||||
virtual void Visit(BfTypeDeclaration* typeDeclaration) override;
|
||||
virtual void Visit(BfUsingDirective* usingDirective) override;
|
||||
virtual void Visit(BfUsingStaticDirective* usingDirective) override;
|
||||
virtual void Visit(BfNamespaceDeclaration* namespaceDeclaration) override;
|
||||
virtual void Visit(BfBlock* block) override;
|
||||
virtual void Visit(BfRootNode* rootNode) override;
|
||||
};
|
||||
|
||||
NS_BF_END
|
153
IDEHelper/Compiler/BfDeferEvalChecker.cpp
Normal file
153
IDEHelper/Compiler/BfDeferEvalChecker.cpp
Normal file
|
@ -0,0 +1,153 @@
|
|||
#include "BfDeferEvalChecker.h"
|
||||
|
||||
USING_NS_BF;
|
||||
|
||||
BfDeferEvalChecker::BfDeferEvalChecker()
|
||||
{
|
||||
mNeedsDeferEval = false;
|
||||
}
|
||||
|
||||
void BfDeferEvalChecker::Visit(BfAstNode* attribExpr)
|
||||
{
|
||||
mNeedsDeferEval = false;
|
||||
}
|
||||
|
||||
void BfDeferEvalChecker::Visit(BfLiteralExpression* literalExpr)
|
||||
{
|
||||
switch (literalExpr->mValue.mTypeCode)
|
||||
{
|
||||
case BfTypeCode_Boolean:
|
||||
case BfTypeCode_Char8:
|
||||
case BfTypeCode_Int8:
|
||||
case BfTypeCode_UInt8:
|
||||
case BfTypeCode_Int16:
|
||||
case BfTypeCode_UInt16:
|
||||
case BfTypeCode_Int32:
|
||||
case BfTypeCode_UInt32:
|
||||
case BfTypeCode_Int64:
|
||||
case BfTypeCode_UInt64:
|
||||
case BfTypeCode_IntPtr:
|
||||
case BfTypeCode_UIntPtr:
|
||||
case BfTypeCode_IntUnknown:
|
||||
case BfTypeCode_UIntUnknown:
|
||||
mNeedsDeferEval = true;
|
||||
break;
|
||||
default:
|
||||
mNeedsDeferEval = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void BfDeferEvalChecker::Visit(BfCastExpression* castExpr)
|
||||
{
|
||||
if (auto namedTypeRef = BfNodeDynCastExact<BfNamedTypeReference>(castExpr->mTypeRef))
|
||||
{
|
||||
if (namedTypeRef->ToString() == "ExpectedType")
|
||||
{
|
||||
mNeedsDeferEval = true;
|
||||
}
|
||||
}
|
||||
else if (auto dotTypeRef = BfNodeDynCastExact<BfDotTypeReference>(castExpr->mTypeRef))
|
||||
{
|
||||
mNeedsDeferEval = true;
|
||||
}
|
||||
}
|
||||
|
||||
void BfDeferEvalChecker::Visit(BfParenthesizedExpression* parenExpr)
|
||||
{
|
||||
VisitChild(parenExpr->mExpression);
|
||||
}
|
||||
|
||||
void BfDeferEvalChecker::Visit(BfTupleExpression* tupleExpr)
|
||||
{
|
||||
bool needDeferEval = false;
|
||||
for (auto element : tupleExpr->mValues)
|
||||
{
|
||||
VisitChild(element);
|
||||
needDeferEval |= mNeedsDeferEval;
|
||||
}
|
||||
|
||||
mNeedsDeferEval = needDeferEval;
|
||||
}
|
||||
|
||||
void BfDeferEvalChecker::Visit(BfMemberReferenceExpression* memberRefExpr)
|
||||
{
|
||||
// Dotted name?
|
||||
mNeedsDeferEval = (memberRefExpr->mTarget == NULL);
|
||||
}
|
||||
|
||||
void BfDeferEvalChecker::Visit(BfInvocationExpression* invocationExpr)
|
||||
{
|
||||
VisitChild(invocationExpr->mTarget);
|
||||
}
|
||||
|
||||
void BfDeferEvalChecker::Visit(BfConditionalExpression* condExpr)
|
||||
{
|
||||
VisitChild(condExpr->mTrueExpression);
|
||||
bool prev = mNeedsDeferEval;
|
||||
VisitChild(condExpr->mFalseExpression);
|
||||
mNeedsDeferEval |= prev;
|
||||
}
|
||||
|
||||
void BfDeferEvalChecker::Visit(BfUnaryOperatorExpression* unaryOpExpr)
|
||||
{
|
||||
switch (unaryOpExpr->mOp)
|
||||
{
|
||||
case BfUnaryOp_Negate:
|
||||
case BfUnaryOp_Positive:
|
||||
case BfUnaryOp_InvertBits:
|
||||
VisitChild(unaryOpExpr->mExpression);
|
||||
break;
|
||||
// case BfUnaryOp_Params:
|
||||
// mNeedsDeferEval = true;
|
||||
// break;
|
||||
default:
|
||||
mNeedsDeferEval = false;
|
||||
}
|
||||
}
|
||||
|
||||
void BfDeferEvalChecker::Visit(BfObjectCreateExpression * objCreateExpr)
|
||||
{
|
||||
if (objCreateExpr->mTypeRef != NULL)
|
||||
{
|
||||
if (objCreateExpr->mTypeRef->IsExact<BfDotTypeReference>())
|
||||
mNeedsDeferEval = true;
|
||||
}
|
||||
}
|
||||
|
||||
void BfDeferEvalChecker::Visit(BfBinaryOperatorExpression* binOpExpr)
|
||||
{
|
||||
switch (binOpExpr->mOp)
|
||||
{
|
||||
case BfBinaryOp_Add:
|
||||
case BfBinaryOp_Subtract:
|
||||
case BfBinaryOp_Multiply:
|
||||
case BfBinaryOp_Divide:
|
||||
case BfBinaryOp_Modulus:
|
||||
case BfBinaryOp_BitwiseAnd:
|
||||
case BfBinaryOp_BitwiseOr:
|
||||
case BfBinaryOp_ExclusiveOr:
|
||||
case BfBinaryOp_LeftShift:
|
||||
case BfBinaryOp_RightShift:
|
||||
case BfBinaryOp_GreaterThan:
|
||||
case BfBinaryOp_LessThan:
|
||||
case BfBinaryOp_GreaterThanOrEqual:
|
||||
case BfBinaryOp_LessThanOrEqual:
|
||||
{
|
||||
VisitChild(binOpExpr->mLeft);
|
||||
bool prev = mNeedsDeferEval;
|
||||
VisitChild(binOpExpr->mRight);
|
||||
mNeedsDeferEval |= prev;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
mNeedsDeferEval = false;
|
||||
}
|
||||
}
|
||||
|
||||
void BfDeferEvalChecker::Visit(BfDefaultExpression* defaultExpr)
|
||||
{
|
||||
if (defaultExpr->mTypeRef == NULL)
|
||||
mNeedsDeferEval = true;
|
||||
}
|
||||
|
32
IDEHelper/Compiler/BfDeferEvalChecker.h
Normal file
32
IDEHelper/Compiler/BfDeferEvalChecker.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
|
||||
#include "BeefySysLib/Common.h"
|
||||
#include "BfAst.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
class BfDeferEvalChecker : public BfStructuralVisitor
|
||||
{
|
||||
public:
|
||||
bool mNeedsDeferEval;
|
||||
|
||||
public:
|
||||
BfDeferEvalChecker();
|
||||
|
||||
virtual void Visit(BfAstNode* node) override;
|
||||
|
||||
virtual void Visit(BfLiteralExpression* literalExpr) override;
|
||||
virtual void Visit(BfCastExpression* castExpr) override;
|
||||
virtual void Visit(BfParenthesizedExpression* parenExpr) override;
|
||||
virtual void Visit(BfTupleExpression* tupleExpr) override;
|
||||
virtual void Visit(BfMemberReferenceExpression* memberRefExpr) override;
|
||||
virtual void Visit(BfInvocationExpression* invocationExpr) override;
|
||||
virtual void Visit(BfConditionalExpression* condExpr) override;
|
||||
virtual void Visit(BfUnaryOperatorExpression* unaryOpExpr) override;
|
||||
virtual void Visit(BfObjectCreateExpression* objCreateExpr) override;
|
||||
virtual void Visit(BfBinaryOperatorExpression* binOpExpr) override;
|
||||
virtual void Visit(BfDefaultExpression* defaultExpr) override;
|
||||
};
|
||||
|
||||
|
||||
NS_BF_END
|
2527
IDEHelper/Compiler/BfDemangler.cpp
Normal file
2527
IDEHelper/Compiler/BfDemangler.cpp
Normal file
File diff suppressed because it is too large
Load diff
130
IDEHelper/Compiler/BfDemangler.h
Normal file
130
IDEHelper/Compiler/BfDemangler.h
Normal file
|
@ -0,0 +1,130 @@
|
|||
#pragma once
|
||||
|
||||
#include "BeefySysLib/Common.h"
|
||||
#include "../DebugCommon.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
typedef Array<String> SubstituteList;
|
||||
|
||||
class DemangleBase
|
||||
{
|
||||
public:
|
||||
DbgLanguage mLanguage;
|
||||
int mCurIdx;
|
||||
String mResult;
|
||||
bool mFailed;
|
||||
String mMangledName;
|
||||
SubstituteList mSubstituteList;
|
||||
bool mInArgs;
|
||||
bool mBeefFixed;
|
||||
|
||||
public:
|
||||
DemangleBase();
|
||||
|
||||
bool Failed();
|
||||
void Require(bool result);
|
||||
};
|
||||
|
||||
class DwDemangler : public DemangleBase
|
||||
{
|
||||
public:
|
||||
SubstituteList mTemplateList;
|
||||
bool mIsFirstName;
|
||||
int mTemplateDepth;
|
||||
bool mOmitSubstituteAdd;
|
||||
bool mCaptureTargetType;
|
||||
bool mFunctionPopSubstitute;
|
||||
bool mRawDemangle;
|
||||
|
||||
public:
|
||||
bool DemangleEnd();
|
||||
bool DemangleArrayType(StringImpl& outName);
|
||||
bool DemangleBuiltinType(StringImpl& outName);
|
||||
bool DemangleFunctionType(StringImpl& outName);
|
||||
bool DemangleSourceName(StringImpl& outName);
|
||||
bool DemangleRefQualifier(StringImpl& outName);
|
||||
bool DemangleType(StringImpl& outName);
|
||||
bool DemangleNestedName(StringImpl& outName);
|
||||
bool DemangleCVQualifiers(StringImpl& outName);
|
||||
bool DemangleOperatorName(StringImpl& outName);
|
||||
bool DemangleExprPriamry(StringImpl& outName);
|
||||
bool DemangleTemplateArgPack(StringImpl& outName);
|
||||
bool DemangleTemplateArg(StringImpl& outName);
|
||||
bool DemangleTemplateArgs(StringImpl& outName);
|
||||
bool DemangleUnqualifiedName(StringImpl& outName);
|
||||
bool DemangleInternalName(StringImpl& outName);
|
||||
bool DemangleSubstitution(StringImpl& outName);
|
||||
bool DemangleTemplateParam(StringImpl& outName);
|
||||
bool DemangleUnscopedName(StringImpl& outName);
|
||||
bool DemangleClassEnumType(StringImpl& outName);
|
||||
bool DemangleLocalName(StringImpl& outName);
|
||||
bool DemangleName(StringImpl& outName, bool* outHasTemplateArgs = NULL);
|
||||
bool DemangleFunction(StringImpl& outName);
|
||||
|
||||
public:
|
||||
DwDemangler();
|
||||
|
||||
String Demangle(const StringImpl& mangledName);
|
||||
};
|
||||
|
||||
class MsDemangler : public DemangleBase
|
||||
{
|
||||
public:
|
||||
int mCurIdx;
|
||||
|
||||
public:
|
||||
int DemangleNumber();
|
||||
bool DemangleString(StringImpl& outName);
|
||||
bool DemangleTemplateName(StringImpl& outName, String* primaryName = NULL);
|
||||
bool DemangleCV(StringImpl& outName);
|
||||
bool DemangleModifiedType(StringImpl& outName, bool isPtr);
|
||||
bool DemangleType(StringImpl& outName);
|
||||
bool DemangleScopedName(StringImpl& outName, String* primaryName = NULL);
|
||||
bool DemangleName(StringImpl& outName);
|
||||
static bool IsData(const StringImpl& mangledName);
|
||||
|
||||
public:
|
||||
MsDemangler();
|
||||
|
||||
String Demangle(const StringImpl& mangledName);
|
||||
};
|
||||
|
||||
class MsDemangleScanner : public DemangleBase
|
||||
{
|
||||
public:
|
||||
bool mIsData;
|
||||
|
||||
public:
|
||||
int DemangleNumber();
|
||||
bool DemangleString();
|
||||
bool DemangleTemplateName();
|
||||
bool DemangleCV();
|
||||
bool DemangleModifiedType(bool isPtr);
|
||||
bool DemangleType();
|
||||
bool DemangleScopedName();
|
||||
bool DemangleName();
|
||||
|
||||
public:
|
||||
MsDemangleScanner();
|
||||
|
||||
void Process(const StringImpl& mangledName);
|
||||
};
|
||||
|
||||
class BfDemangler
|
||||
{
|
||||
public:
|
||||
enum Flags
|
||||
{
|
||||
Flag_None,
|
||||
Flag_CaptureTargetType = 1,
|
||||
Flag_RawDemangle = 2,
|
||||
Flag_BeefFixed = 4
|
||||
};
|
||||
|
||||
public:
|
||||
static String Demangle(const StringImpl& mangledName, DbgLanguage language, Flags flags = Flag_None);
|
||||
static bool IsData(const StringImpl& mangledName);
|
||||
};
|
||||
|
||||
NS_BF_END
|
1193
IDEHelper/Compiler/BfElementVisitor.cpp
Normal file
1193
IDEHelper/Compiler/BfElementVisitor.cpp
Normal file
File diff suppressed because it is too large
Load diff
135
IDEHelper/Compiler/BfElementVisitor.h
Normal file
135
IDEHelper/Compiler/BfElementVisitor.h
Normal file
|
@ -0,0 +1,135 @@
|
|||
#pragma once
|
||||
|
||||
#include "BfAst.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
class BfElementVisitor : public BfStructuralVisitor
|
||||
{
|
||||
public:
|
||||
BfElementVisitor();
|
||||
|
||||
virtual void Visit(BfAstNode* bfAstNode) {}
|
||||
virtual void Visit(BfErrorNode* bfErrorNode) {}
|
||||
virtual void Visit(BfScopeNode* scopeNode);
|
||||
virtual void Visit(BfNewNode* newNode);
|
||||
virtual void Visit(BfLabeledBlock* labeledBlock);
|
||||
virtual void Visit(BfExpression* expr);
|
||||
virtual void Visit(BfExpressionStatement* exprStmt);
|
||||
virtual void Visit(BfAttributedExpression* attribExpr);
|
||||
virtual void Visit(BfStatement* stmt);
|
||||
virtual void Visit(BfLabelableStatement* labelableStmt);
|
||||
virtual void Visit(BfTypedValueExpression* typedValueExpr);
|
||||
|
||||
virtual void Visit(BfCommentNode* commentNode);
|
||||
virtual void Visit(BfPreprocesorIgnoredSectionNode* preprocesorIgnoredSection);
|
||||
virtual void Visit(BfPreprocessorNode* preprocessorNode);
|
||||
virtual void Visit(BfPreprocessorDefinedExpression* definedExpr);
|
||||
|
||||
virtual void Visit(BfAttributeDirective* attributeDirective);
|
||||
virtual void Visit(BfGenericParamsDeclaration* genericParams);
|
||||
virtual void Visit(BfGenericConstraintsDeclaration* genericConstraints);
|
||||
virtual void Visit(BfGenericArgumentsNode* genericArgumentsNode);
|
||||
|
||||
virtual void Visit(BfEmptyStatement* emptyStmt);
|
||||
virtual void Visit(BfTokenNode* tokenNode);
|
||||
virtual void Visit(BfTokenPairNode* tokenPairNode);
|
||||
virtual void Visit(BfLiteralExpression* literalExpr);
|
||||
virtual void Visit(BfIdentifierNode* identifierNode);
|
||||
virtual void Visit(BfAttributedIdentifierNode* attrIdentifierNode);
|
||||
virtual void Visit(BfQualifiedNameNode* nameNode);
|
||||
virtual void Visit(BfThisExpression* thisExpr);
|
||||
virtual void Visit(BfBaseExpression* baseExpr);
|
||||
virtual void Visit(BfMixinExpression* thisExpr);
|
||||
virtual void Visit(BfSizedArrayCreateExpression* createExpr);
|
||||
virtual void Visit(BfCollectionInitializerExpression* collectionInitExpr);
|
||||
virtual void Visit(BfArraySizeSpecifier* arraySizeSpecifier);
|
||||
virtual void Visit(BfTypeReference* typeRef);
|
||||
virtual void Visit(BfNamedTypeReference* typeRef);
|
||||
virtual void Visit(BfQualifiedTypeReference* qualifiedType);
|
||||
virtual void Visit(BfDotTypeReference* typeRef);
|
||||
virtual void Visit(BfVarTypeReference* typeRef);
|
||||
virtual void Visit(BfVarRefTypeReference* typeRef);
|
||||
virtual void Visit(BfLetTypeReference* typeRef);
|
||||
virtual void Visit(BfConstTypeRef* typeRef);
|
||||
virtual void Visit(BfConstExprTypeRef* typeRef);
|
||||
virtual void Visit(BfRefTypeRef* typeRef);
|
||||
virtual void Visit(BfRetTypeTypeRef* typeRef);
|
||||
virtual void Visit(BfArrayTypeRef* typeRef);
|
||||
virtual void Visit(BfGenericInstanceTypeRef* typeRef);
|
||||
virtual void Visit(BfTupleTypeRef* typeRef);
|
||||
virtual void Visit(BfDeclTypeRef* typeRef);
|
||||
virtual void Visit(BfDelegateTypeRef* typeRef);
|
||||
virtual void Visit(BfPointerTypeRef* typeRef);
|
||||
virtual void Visit(BfNullableTypeRef* typeRef);
|
||||
virtual void Visit(BfVariableDeclaration* varDecl);
|
||||
virtual void Visit(BfLocalMethodDeclaration* methodDecl);
|
||||
virtual void Visit(BfParameterDeclaration* paramDecl);
|
||||
virtual void Visit(BfParamsExpression* paramsExpr);
|
||||
virtual void Visit(BfTypeAttrExpression* typeAttrExpr);
|
||||
virtual void Visit(BfDefaultExpression* defaultExpr);
|
||||
virtual void Visit(BfUninitializedExpression* uninitializedExpr);
|
||||
virtual void Visit(BfCheckTypeExpression* checkTypeExpr);
|
||||
virtual void Visit(BfDynamicCastExpression* dynCastExpr);
|
||||
virtual void Visit(BfCastExpression* castExpr);
|
||||
virtual void Visit(BfDelegateBindExpression* delegateBindExpr);
|
||||
virtual void Visit(BfLambdaBindExpression* lambdaBindExpr);
|
||||
virtual void Visit(BfObjectCreateExpression* objCreateExpr);
|
||||
virtual void Visit(BfBoxExpression* boxExpr);
|
||||
virtual void Visit(BfScopedInvocationTarget* scopedTarget);
|
||||
virtual void Visit(BfInvocationExpression* invocationExpr);
|
||||
virtual void Visit(BfDeferStatement* deferStmt);
|
||||
virtual void Visit(BfEnumCaseBindExpression* caseBindExpr);
|
||||
virtual void Visit(BfCaseExpression* caseExpr);
|
||||
virtual void Visit(BfSwitchCase* switchCase);
|
||||
virtual void Visit(BfWhenExpression* whenExpr);
|
||||
virtual void Visit(BfSwitchStatement* switchStmt);
|
||||
virtual void Visit(BfTryStatement* tryStmt);
|
||||
virtual void Visit(BfCatchStatement* catchStmt);
|
||||
virtual void Visit(BfFinallyStatement* finallyStmt);
|
||||
virtual void Visit(BfCheckedStatement* checkedStmt);
|
||||
virtual void Visit(BfUncheckedStatement* uncheckedStmt);
|
||||
virtual void Visit(BfIfStatement* ifStmt);
|
||||
virtual void Visit(BfThrowStatement* throwStmt);
|
||||
virtual void Visit(BfDeleteStatement* deleteStmt);
|
||||
virtual void Visit(BfReturnStatement* returnStmt);
|
||||
virtual void Visit(BfYieldStatement* returnStmt);
|
||||
virtual void Visit(BfBreakStatement* breakStmt);
|
||||
virtual void Visit(BfContinueStatement* continueStmt);
|
||||
virtual void Visit(BfFallthroughStatement* fallthroughStmt);
|
||||
virtual void Visit(BfUsingStatement* whileStmt);
|
||||
virtual void Visit(BfDoStatement* whileStmt);
|
||||
virtual void Visit(BfRepeatStatement* repeatStmt);
|
||||
virtual void Visit(BfWhileStatement* whileStmt);
|
||||
virtual void Visit(BfForStatement* forStmt);
|
||||
virtual void Visit(BfForEachStatement* forEachStmt);
|
||||
virtual void Visit(BfConditionalExpression* condExpr);
|
||||
virtual void Visit(BfAssignmentExpression* assignExpr);
|
||||
virtual void Visit(BfParenthesizedExpression* parenExpr);
|
||||
virtual void Visit(BfTupleExpression* parenExpr);
|
||||
virtual void Visit(BfMemberReferenceExpression* memberRefExpr);
|
||||
virtual void Visit(BfIndexerExpression* indexerExpr);
|
||||
virtual void Visit(BfUnaryOperatorExpression* binOpExpr);
|
||||
virtual void Visit(BfBinaryOperatorExpression* binOpExpr);
|
||||
virtual void Visit(BfConstructorDeclaration* ctorDeclaration);
|
||||
virtual void Visit(BfDestructorDeclaration* dtorDeclaration);
|
||||
virtual void Visit(BfMethodDeclaration* methodDeclaration);
|
||||
virtual void Visit(BfOperatorDeclaration* operatorDeclaration);
|
||||
virtual void Visit(BfPropertyMethodDeclaration* propertyDeclaration);
|
||||
virtual void Visit(BfPropertyDeclaration* propertyDeclaration);
|
||||
virtual void Visit(BfIndexerDeclaration* indexerDeclaration);
|
||||
virtual void Visit(BfFieldDeclaration* fieldDeclaration);
|
||||
virtual void Visit(BfEnumCaseDeclaration* enumCaseDeclaration);
|
||||
virtual void Visit(BfFieldDtorDeclaration* fieldDtorDeclaration);
|
||||
virtual void Visit(BfTypeDeclaration* typeDeclaration);
|
||||
virtual void Visit(BfTypeAliasDeclaration* typeDeclaration);
|
||||
virtual void Visit(BfUsingDirective* usingDirective);
|
||||
virtual void Visit(BfUsingStaticDirective* usingDirective);
|
||||
virtual void Visit(BfNamespaceDeclaration* namespaceDeclaration);
|
||||
virtual void Visit(BfBlock* block);
|
||||
virtual void Visit(BfRootNode* rootNode);
|
||||
virtual void Visit(BfInlineAsmStatement* asmStmt);
|
||||
virtual void Visit(BfInlineAsmInstruction* asmInst);
|
||||
};
|
||||
|
||||
NS_BF_END
|
17260
IDEHelper/Compiler/BfExprEvaluator.cpp
Normal file
17260
IDEHelper/Compiler/BfExprEvaluator.cpp
Normal file
File diff suppressed because it is too large
Load diff
430
IDEHelper/Compiler/BfExprEvaluator.h
Normal file
430
IDEHelper/Compiler/BfExprEvaluator.h
Normal file
|
@ -0,0 +1,430 @@
|
|||
#pragma once
|
||||
|
||||
#include "BfCompiler.h"
|
||||
#include "BfSourceClassifier.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
enum BfArgFlags
|
||||
{
|
||||
BfArgFlag_None = 0,
|
||||
BfArgFlag_DelegateBindAttempt = 1,
|
||||
BfArgFlag_LambdaBindAttempt = 2,
|
||||
BfArgFlag_UnqualifiedDotAttempt = 4,
|
||||
BfArgFlag_DeferredValue = 8,
|
||||
BfArgFlag_FromParamComposite = 0x10,
|
||||
BfArgFlag_UntypedDefault = 0x20,
|
||||
BfArgFlag_DeferredEval = 0x40,
|
||||
BfArgFlag_ExpectedTypeCast = 0x80,
|
||||
BfArgFlag_VariableDeclaration = 0x100,
|
||||
BfArgFlag_ParamsExpr = 0x200
|
||||
};
|
||||
|
||||
enum BfResolveArgFlags
|
||||
{
|
||||
BfResolveArgFlag_None = 0,
|
||||
BfResolveArgFlag_DeferFixits = 1,
|
||||
BfResolveArgFlag_DeferParamValues = 2, // We still evaluate but don't generate code until the method is selected (for SkipCall support)
|
||||
BfResolveArgFlag_DeferParamEval = 4,
|
||||
BfResolveArgFlag_AllowUnresolvedTypes = 8,
|
||||
};
|
||||
|
||||
class BfResolvedArg
|
||||
{
|
||||
public:
|
||||
BfTypedValue mTypedValue;
|
||||
BfType* mResolvedType;
|
||||
BfAstNode* mExpression;
|
||||
BfArgFlags mArgFlags;
|
||||
BfType* mExpectedType;
|
||||
BfType* mBestBoundType;
|
||||
bool mWantsRecalc;
|
||||
|
||||
public:
|
||||
BfResolvedArg()
|
||||
{
|
||||
mResolvedType = NULL;
|
||||
mExpression = NULL;
|
||||
mArgFlags = BfArgFlag_None;
|
||||
mExpectedType = NULL;
|
||||
mBestBoundType = NULL;
|
||||
mWantsRecalc = false;
|
||||
}
|
||||
|
||||
bool IsDeferredEval()
|
||||
{
|
||||
return (mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt | BfArgFlag_UntypedDefault | BfArgFlag_DeferredEval)) != 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct BfResolvedArgs
|
||||
{
|
||||
SizedArray<BfResolvedArg, 4> mResolvedArgs;
|
||||
BfTokenNode* mOpenToken;
|
||||
const BfSizedArray<BfExpression*>* mArguments;
|
||||
const BfSizedArray<BfTokenNode*>* mCommas;
|
||||
BfTokenNode* mCloseToken;
|
||||
|
||||
public:
|
||||
BfResolvedArgs()
|
||||
{
|
||||
mOpenToken = NULL;
|
||||
mArguments = NULL;
|
||||
mCommas = NULL;
|
||||
mCloseToken = NULL;
|
||||
}
|
||||
|
||||
BfResolvedArgs(BfSizedArray<BfExpression*>* args)
|
||||
{
|
||||
mOpenToken = NULL;
|
||||
mArguments = args;
|
||||
mCommas = NULL;
|
||||
mCloseToken = NULL;
|
||||
}
|
||||
|
||||
BfResolvedArgs(BfTokenNode* openToken, BfSizedArray<BfExpression*>* args, BfSizedArray<BfTokenNode*>* commas, BfTokenNode* closeToken)
|
||||
{
|
||||
mOpenToken = openToken;
|
||||
mArguments = args;
|
||||
mCommas = commas;
|
||||
mCloseToken = closeToken;
|
||||
}
|
||||
|
||||
void Init(const BfSizedArray<BfExpression*>* args)
|
||||
{
|
||||
mOpenToken = NULL;
|
||||
mArguments = args;
|
||||
mCommas = NULL;
|
||||
mCloseToken = NULL;
|
||||
}
|
||||
|
||||
void HandleFixits(BfModule* module);
|
||||
};
|
||||
|
||||
class BfMethodMatcher
|
||||
{
|
||||
public:
|
||||
struct BfAmbiguousEntry
|
||||
{
|
||||
BfMethodInstance* mMethodInstance;
|
||||
BfTypeVector mBestMethodGenericArguments;
|
||||
};
|
||||
|
||||
enum MatchFailKind
|
||||
{
|
||||
MatchFailKind_None,
|
||||
MatchFailKind_Protection,
|
||||
MatchFailKind_CheckedMismatch
|
||||
};
|
||||
|
||||
public:
|
||||
BfAstNode* mTargetSrc;
|
||||
BfModule* mModule;
|
||||
String mMethodName;
|
||||
BfMethodInstance* mInterfaceMethodInstance;
|
||||
SizedArrayImpl<BfResolvedArg>& mArguments;
|
||||
BfMethodType mMethodType;
|
||||
BfCheckedKind mCheckedKind;
|
||||
bool mHadExplicitGenericArguments;
|
||||
bool mHasVarArguments;
|
||||
bool mBypassVirtual;
|
||||
bool mAllowImplicitThis;
|
||||
bool mAllowStatic;
|
||||
bool mAllowNonStatic;
|
||||
bool mSkipImplicitParams;
|
||||
int mMethodCheckCount;
|
||||
int mInferGenericProgressIdx;
|
||||
BfType* mExplicitInterfaceCheck;
|
||||
MatchFailKind mMatchFailKind;
|
||||
|
||||
BfTypeVector mCheckMethodGenericArguments;
|
||||
SizedArray<BfIRValue, 4> mPrevArgValues;
|
||||
|
||||
BfType* mSelfType; // Only when matching interfaces when 'Self' needs to refer back to the implementing type
|
||||
BfMethodDef* mBackupMethodDef;
|
||||
BfMethodDef* mBestMethodDef;
|
||||
BfTypeInstance* mBestMethodTypeInstance;
|
||||
BfModuleMethodInstance mBestMethodInstance;
|
||||
SizedArray<int, 4> mBestMethodGenericArgumentSrcs;
|
||||
BfTypeVector mBestMethodGenericArguments;
|
||||
BfTypeVector mExplicitMethodGenericArguments;
|
||||
bool mFakeConcreteTarget;
|
||||
Array<BfAmbiguousEntry> mAmbiguousEntries;
|
||||
|
||||
public:
|
||||
BfTypedValue ResolveArgTypedValue(BfResolvedArg& resolvedArg, BfType* checkType);
|
||||
bool InferGenericArgument(BfMethodInstance* methodInstance, BfType* argType, BfType* wantType, BfIRValue argValue);
|
||||
void CompareMethods(BfMethodInstance* prevMethodInstance, BfTypeVector* prevGenericArgumentsSubstitute,
|
||||
BfMethodInstance* newMethodInstance, BfTypeVector* genericArgumentsSubstitute,
|
||||
bool* outNewIsBetter, bool* outNewIsWorse, bool allowSpecializeFail);
|
||||
void FlushAmbiguityError();
|
||||
|
||||
public:
|
||||
BfMethodMatcher(BfAstNode* targetSrc, BfModule* module, const StringImpl& methodName, SizedArrayImpl<BfResolvedArg>& arguments, BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArguments);
|
||||
BfMethodMatcher(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* interfaceMethodInstance, SizedArrayImpl<BfResolvedArg>& arguments, BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArguments = NULL);
|
||||
void Init(/*SizedArrayImpl<BfResolvedArg>& arguments, */BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArguments);
|
||||
bool CheckType(BfTypeInstance* typeInstance, BfTypedValue target, bool isFailurePass);
|
||||
void CheckOuterTypeStaticMethods(BfTypeInstance* typeInstance, bool isFailurePass);
|
||||
bool WantsCheckMethod(BfProtectionCheckFlags& flags, BfTypeInstance* startTypeInstance, BfTypeInstance* checkTypeInstance, BfMethodDef* methodDef);
|
||||
bool CheckMethod(BfTypeInstance* typeInstance, BfMethodDef* checkMethod, bool isFailurePass);
|
||||
void TryDevirtualizeCall(BfTypedValue target);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class BfBaseClassWalker
|
||||
{
|
||||
public:
|
||||
struct Entry
|
||||
{
|
||||
BfType* mSrcType;
|
||||
BfTypeInstance* mTypeInstance;
|
||||
|
||||
Entry(BfType* srcType, BfTypeInstance* typeInstance)
|
||||
{
|
||||
mSrcType = srcType;
|
||||
mTypeInstance = typeInstance;
|
||||
}
|
||||
|
||||
Entry()
|
||||
{
|
||||
mSrcType = NULL;
|
||||
mTypeInstance = NULL;
|
||||
}
|
||||
|
||||
bool operator==(const Entry& rhs)
|
||||
{
|
||||
return (mSrcType == rhs.mSrcType) && (mTypeInstance == rhs.mTypeInstance);
|
||||
}
|
||||
};
|
||||
|
||||
BfTypeInstance* mTypes[2];
|
||||
Array<Entry> mManualList;
|
||||
bool mMayBeFromInterface;
|
||||
|
||||
public:
|
||||
BfBaseClassWalker();
|
||||
BfBaseClassWalker(BfType* typeA, BfType* typeB, BfModule* module);
|
||||
void AddConstraints(BfType* srcType, BfGenericParamInstance* genericParam);
|
||||
|
||||
public:
|
||||
Entry Next();
|
||||
};
|
||||
|
||||
class BfFunctionBindResult
|
||||
{
|
||||
public:
|
||||
BfTypedValue mOrigTarget;
|
||||
BfTypedValue mTarget;
|
||||
BfIRValue mFunc;
|
||||
BfMethodInstance* mMethodInstance;
|
||||
bool mSkipThis;
|
||||
bool mWantsArgs;
|
||||
bool mCheckedMultipleMethods;
|
||||
SizedArray<BfIRValue, 2> mIRArgs;
|
||||
|
||||
public:
|
||||
BfFunctionBindResult()
|
||||
{
|
||||
mMethodInstance = NULL;
|
||||
mWantsArgs = false;
|
||||
mSkipThis = false;
|
||||
mCheckedMultipleMethods = false;
|
||||
}
|
||||
};
|
||||
|
||||
struct DeferredTupleAssignData
|
||||
{
|
||||
struct Entry
|
||||
{
|
||||
BfExpression* mExpr;
|
||||
BfExprEvaluator* mExprEvaluator;
|
||||
DeferredTupleAssignData* mInnerTuple;
|
||||
};
|
||||
|
||||
Array<Entry> mChildren;
|
||||
BfTupleType* mTupleType;
|
||||
|
||||
~DeferredTupleAssignData();
|
||||
};
|
||||
|
||||
enum BfImplicitParamKind
|
||||
{
|
||||
BfImplicitParamKind_General,
|
||||
BfImplicitParamKind_GenericMethodMember,
|
||||
BfImplicitParamKind_GenericTypeMember,
|
||||
BfImplicitParamKind_GenericTypeMember_Addr,
|
||||
};
|
||||
|
||||
enum BfLookupFieldFlags
|
||||
{
|
||||
BfLookupFieldFlag_None = 0,
|
||||
BfLookupFieldFlag_IsImplicitThis = 1,
|
||||
BfLookupFieldFlag_CheckingOuter = 2
|
||||
};
|
||||
|
||||
enum BfBinOpFlags
|
||||
{
|
||||
BfBinOpFlag_None = 0,
|
||||
BfBinOpFlag_NoClassify = 1,
|
||||
BfBinOpFlag_ForceLeftType = 2
|
||||
};
|
||||
|
||||
class BfExprEvaluator : public BfStructuralVisitor
|
||||
{
|
||||
public:
|
||||
BfModule* mModule;
|
||||
BfTypedValue mResult;
|
||||
BfEvalExprFlags mBfEvalExprFlags;
|
||||
BfLocalVariable* mResultLocalVar;
|
||||
int mResultLocalVarField;
|
||||
int mResultLocalVarFieldCount; // > 1 for structs with multiple members
|
||||
BfAstNode* mResultLocalVarRefNode;
|
||||
BfAstNode* mPropSrc;
|
||||
BfTypedValue mPropTarget;
|
||||
BfTypedValue mOrigPropTarget;
|
||||
BfGetMethodInstanceFlags mPropGetMethodFlags;
|
||||
BfCheckedKind mPropCheckedKind;
|
||||
BfPropertyDef* mPropDef;
|
||||
BfType* mExpectingType;
|
||||
BfAttributeState* mPrefixedAttributeState;
|
||||
BfTypedValue* mReceivingValue;
|
||||
BfFunctionBindResult* mFunctionBindResult;
|
||||
SizedArray<BfResolvedArg, 2> mIndexerValues;
|
||||
BfAstNode* mDeferCallRef;
|
||||
BfScopeData* mDeferScopeAlloc;
|
||||
bool mUsedAsStatement;
|
||||
bool mPropDefBypassVirtual;
|
||||
bool mExplicitCast;
|
||||
bool mResolveGenericParam;
|
||||
bool mNoBind;
|
||||
bool mIsVolatileReference;
|
||||
bool mIsHeapReference;
|
||||
bool mResultIsTempComposite;
|
||||
bool mAllowReadOnlyReference;
|
||||
|
||||
public:
|
||||
BfExprEvaluator(BfModule* module);
|
||||
~BfExprEvaluator();
|
||||
|
||||
void GetLiteral(BfAstNode* refNode, const BfVariant& variant);
|
||||
void FinishExpressionResult();
|
||||
virtual bool CheckAllowValue(const BfTypedValue& typedValue, BfAstNode* refNode);
|
||||
BfAutoComplete* GetAutoComplete();
|
||||
BfTypedValue SetupNullConditional(BfTypedValue target, BfTokenNode* dotToken);
|
||||
void Evaluate(BfAstNode* astNode, bool propogateNullConditional = false, bool ignoreNullConditional = false, bool allowSplat = true);
|
||||
BfType* BindGenericType(BfAstNode* node, BfType* bindType);
|
||||
BfType* ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0);
|
||||
void ResolveGenericType();
|
||||
void ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveArgFlags flags = BfResolveArgFlag_None);
|
||||
BfAllocTarget ResolveAllocTarget(BfAstNode* newNode, BfTokenNode*& newToken);
|
||||
BfTypedValue ResolveArgValue(BfResolvedArg& resolvedArg, BfType* wantType, BfTypedValue* receivingValue = NULL, BfParamKind paramKind = BfParamKind_Normal);
|
||||
BfMethodDef* GetPropertyMethodDef(BfPropertyDef* propDef, BfMethodType methodType, BfCheckedKind checkedKind);
|
||||
BfModuleMethodInstance GetPropertyMethodInstance(BfMethodDef* methodDef);
|
||||
void CheckPropFail(BfMethodDef* propMethodDef, BfMethodInstance* methodInstance);
|
||||
BfTypedValue GetResult(bool clearResult = false, bool resolveGenericType = false);
|
||||
void CheckResultForReading(BfTypedValue& typedValue);
|
||||
void MarkResultUsed();
|
||||
void MarkResultAssigned();
|
||||
void MakeResultAsValue();
|
||||
bool CheckModifyResult(BfTypedValue typeValue, BfAstNode* refNode, const char* modifyType, bool onlyNeedsMut = false);
|
||||
BfTypedValue LookupField(BfAstNode* targetSrc, BfTypedValue target, const StringImpl& fieldName, BfLookupFieldFlags flags = BfLookupFieldFlag_None);
|
||||
void CheckObjectCreateTypeRef(BfType* expectingType, BfAstNode* afterNode);
|
||||
void LookupQualifiedName(BfQualifiedNameNode* nameNode, bool ignoreInitialError = false, bool* hadError = NULL);
|
||||
void LookupQualifiedName(BfAstNode* nameNode, BfIdentifierNode* nameLeft, BfIdentifierNode* nameRight, bool ignoreInitialError, bool* hadError = NULL);
|
||||
void LookupQualifiedStaticField(BfQualifiedNameNode* nameNode, bool ignoreIdentifierNotFoundError);
|
||||
void LookupQualifiedStaticField(BfAstNode* nameNode, BfIdentifierNode* nameLeft, BfIdentifierNode* nameRight, bool ignoreIdentifierNotFoundError);
|
||||
void PerformBinaryOperation(BfType* resultType, BfIRValue convLeftValue, BfIRValue convRightValue, BfBinaryOp binaryOp, BfAstNode* opToken);
|
||||
void PerformBinaryOperation(BfAstNode* leftExpression, BfAstNode* rightExpression, BfBinaryOp binaryOp, BfAstNode* opToken, BfBinOpFlags flags, BfTypedValue leftValue, BfTypedValue rightValue);
|
||||
void PerformBinaryOperation(BfExpression* leftNode, BfExpression* rightNode, BfBinaryOp binaryOp, BfTokenNode* opToken, BfBinOpFlags flags, BfTypedValue leftValue);
|
||||
void PerformBinaryOperation(BfExpression* leftNode, BfExpression* rightNode, BfBinaryOp binaryOp, BfTokenNode* opToken, BfBinOpFlags flags);
|
||||
BfTypedValue LoadLocal(BfLocalVariable* varDecl, bool allowRef = false);
|
||||
BfTypedValue LookupIdentifier(BfAstNode* identifierNode, const StringImpl& findName, bool ignoreInitialError = false, bool* hadError = NULL);
|
||||
BfTypedValue LookupIdentifier(BfIdentifierNode* identifierNode, bool ignoreInitialError = false, bool* hadError = NULL);
|
||||
void AddCallDependencies(BfMethodInstance* methodInstance);
|
||||
BfTypedValue CreateCall(BfMethodInstance* methodInstance, BfIRValue func, bool bypassVirtual, SizedArrayImpl<BfIRValue>& irArgs, BfTypedValue* sret = NULL, bool isTailCall = false);
|
||||
BfTypedValue CreateCall(BfAstNode* targetSrc, const BfTypedValue& target, const BfTypedValue& origTarget, BfMethodDef* methodDef, BfModuleMethodInstance methodInstance, bool bypassVirtual, SizedArrayImpl<BfResolvedArg>& argValues, bool skipThis = false);
|
||||
BfTypedValue CreateCall(BfMethodMatcher* methodMatcher, BfTypedValue target);
|
||||
void MakeBaseConcrete(BfTypedValue& typedValue);
|
||||
void SplatArgs(BfTypedValue value, SizedArrayImpl<BfIRValue>& irArgs);
|
||||
void PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& irArgs, bool disableSplat = false, bool disableLowering = false);
|
||||
void PushThis(BfAstNode* targetSrc, BfTypedValue callTarget, BfMethodInstance* methodInstance, SizedArrayImpl<BfIRValue>& irArgs, bool skipMutCheck = false);
|
||||
BfTypedValue MatchConstructor(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, BfTypeInstance* targetType,
|
||||
BfResolvedArgs& argValues, bool callCtorBodyOnly, bool allowAppendAlloc, BfTypedValue* appendIndexValue = NULL);
|
||||
BfTypedValue CheckEnumCreation(BfAstNode* targetSrc, BfTypeInstance* enumType, const StringImpl& caseName, BfResolvedArgs& argValues);
|
||||
BfTypedValue MatchMethod(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, bool allowImplicitThis, bool bypassVirtual, const StringImpl& name,
|
||||
BfResolvedArgs& argValue, BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArguments, BfCheckedKind checkedKind = BfCheckedKind_NotSet);
|
||||
BfTypedValue MakeCallableTarget(BfAstNode* targetSrc, BfTypedValue target);
|
||||
BfModuleMethodInstance GetSelectedMethod(BfAstNode* targetSrc, BfTypeInstance* curTypeInst, BfMethodDef* methodDef, BfMethodMatcher& methodMatcher);
|
||||
bool CheckVariableDeclaration(BfAstNode* checkNode, bool requireSimpleIfExpr, bool exprMustBeTrue, bool silentFail);
|
||||
bool HasVariableDeclaration(BfAstNode* checkNode);
|
||||
void DoInvocation(BfAstNode* target, BfMethodBoundExpression* methodBoundExpr, const BfSizedArray<BfExpression*>& args, BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArgs, BfTypedValue* outCascadeValue = NULL);
|
||||
int GetMixinVariable();
|
||||
void CheckLocalMethods(BfAstNode* targetSrc, BfTypeInstance* typeInstance, const StringImpl& methodName, BfMethodMatcher& methodMatcher, BfMethodType methodType);
|
||||
void InjectMixin(BfAstNode* targetSrc, BfTypedValue target, bool allowImplicitThis, const StringImpl& name, const BfSizedArray<BfExpression*>& arguments, BfSizedArray<ASTREF(BfTypeReference*)>* methodGenericArgs);
|
||||
void SetMethodElementType(BfAstNode* target);
|
||||
BfTypedValue DoImplicitArgCapture(BfAstNode* refNode, BfIdentifierNode* identifierNode);
|
||||
BfTypedValue DoImplicitArgCapture(BfAstNode* refNode, BfMethodInstance* methodInstance, int paramIdx, bool& failed, BfImplicitParamKind paramKind = BfImplicitParamKind_General, const BfTypedValue& methodRefTarget = BfTypedValue());
|
||||
bool CanBindDelegate(BfDelegateBindExpression* delegateBindExpr, BfMethodInstance** boundMethod = NULL);
|
||||
bool IsExactMethodMatch(BfMethodInstance* methodA, BfMethodInstance* methodB, bool ignoreImplicitParams = false);
|
||||
BfTypeInstance* VerifyBaseDelegateType(BfTypeInstance* delegateType);
|
||||
void ConstResolve(BfExpression* expr);
|
||||
void ProcessArrayInitializer(BfTokenNode* openToken, const BfSizedArray<BfExpression*>& values, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken, int dimensions, SizedArrayImpl<int64>& dimLengths, int dim, bool& hasFailed);
|
||||
BfLambdaInstance* GetLambdaInstance(BfLambdaBindExpression* lambdaBindExpr);
|
||||
void VisitLambdaBodies(BfAstNode* body, BfFieldDtorDeclaration* fieldDtor);
|
||||
void FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType, const StringImpl& fieldName, bool isStatic);
|
||||
void PerformUnaryOperation(BfExpression* unaryOpExpr, BfUnaryOp unaryOp, BfTokenNode* opToken);
|
||||
void PerformAssignment(BfAssignmentExpression* assignExpr, bool evaluatedLeft, BfTypedValue rightValue, BfTypedValue* outCascadeValue = NULL);
|
||||
void PopulateDeferrredTupleAssignData(BfTupleExpression* tupleExr, DeferredTupleAssignData& deferredTupleAssignData);
|
||||
void AssignDeferrredTupleAssignData(BfAssignmentExpression* assignExpr, DeferredTupleAssignData& deferredTupleAssignData, BfTypedValue rightValue);
|
||||
void DoTupleAssignment(BfAssignmentExpression* assignExpr);
|
||||
void FinishDeferredEvals(SizedArrayImpl<BfResolvedArg>& argValues);
|
||||
bool LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifierNode* propName);
|
||||
void DoTypeIntAttr(BfTypeReference* typeRef, BfToken token);
|
||||
//void InitializedSizedArray(BfTupleExpression* createExpr, BfSizedArrayType* arrayType);
|
||||
void InitializedSizedArray(BfSizedArrayType* sizedArrayType, BfTokenNode* openToken, const BfSizedArray<BfExpression*>& values, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken, BfTypedValue* receivingValue = NULL);
|
||||
void DoMemberReference(BfMemberReferenceExpression* memberRefExpr, BfTypedValue* outCascadeValue);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
virtual void Visit(BfTypeReference* typeRef) override;
|
||||
virtual void Visit(BfAttributedExpression* attribExpr) override;
|
||||
virtual void Visit(BfBlock* blockExpr) override;
|
||||
virtual void Visit(BfVariableDeclaration* varDecl) override;
|
||||
virtual void Visit(BfCaseExpression* caseExpr) override;
|
||||
virtual void Visit(BfTypedValueExpression* typedValueExpr) override;
|
||||
virtual void Visit(BfLiteralExpression* literalExpr) override;
|
||||
virtual void Visit(BfIdentifierNode* identifierNode) override;
|
||||
virtual void Visit(BfAttributedIdentifierNode* attrIdentifierNode) override;
|
||||
virtual void Visit(BfQualifiedNameNode* nameNode) override;
|
||||
virtual void Visit(BfThisExpression* thisExpr) override;
|
||||
virtual void Visit(BfBaseExpression* baseExpr) override;
|
||||
virtual void Visit(BfMixinExpression* mixinExpr) override;
|
||||
virtual void Visit(BfSizedArrayCreateExpression* createExpr) override;
|
||||
virtual void Visit(BfCollectionInitializerExpression* initExpr) override;
|
||||
virtual void Visit(BfParamsExpression* paramsExpr) override;
|
||||
virtual void Visit(BfTypeOfExpression* typeOfExpr) override;
|
||||
virtual void Visit(BfSizeOfExpression* sizeOfExpr) override;
|
||||
virtual void Visit(BfAlignOfExpression* alignOfExpr) override;
|
||||
virtual void Visit(BfStrideOfExpression* strideOfExpr) override;
|
||||
virtual void Visit(BfDefaultExpression* defaultExpr) override;
|
||||
virtual void Visit(BfUninitializedExpression* uninitialziedExpr) override;
|
||||
virtual void Visit(BfCheckTypeExpression* checkTypeExpr) override;
|
||||
virtual void Visit(BfDynamicCastExpression* dynCastExpr) override;
|
||||
virtual void Visit(BfCastExpression* castExpr) override;
|
||||
virtual void Visit(BfDelegateBindExpression* delegateBindExpr) override;
|
||||
virtual void Visit(BfLambdaBindExpression* lambdaBindExpr) override;
|
||||
virtual void Visit(BfObjectCreateExpression* objCreateExpr) override;
|
||||
virtual void Visit(BfBoxExpression* boxExpr) override;
|
||||
virtual void Visit(BfInvocationExpression* invocationExpr) override;
|
||||
virtual void Visit(BfConditionalExpression* condExpr) override;
|
||||
virtual void Visit(BfAssignmentExpression* assignExpr) override;
|
||||
virtual void Visit(BfParenthesizedExpression* parenExpr) override;
|
||||
virtual void Visit(BfTupleExpression* tupleExpr) override;
|
||||
virtual void Visit(BfMemberReferenceExpression* memberRefExpr) override;
|
||||
virtual void Visit(BfIndexerExpression* indexerExpr) override;
|
||||
virtual void Visit(BfUnaryOperatorExpression* unaryOpExpr) override;
|
||||
virtual void Visit(BfBinaryOperatorExpression* binOpExpr) override;
|
||||
};
|
||||
|
||||
NS_BF_END
|
71
IDEHelper/Compiler/BfFixits.h
Normal file
71
IDEHelper/Compiler/BfFixits.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
#pragma once
|
||||
|
||||
#include "BfSystem.h"
|
||||
#include "BfAst.h"
|
||||
#include "BfParser.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
class BfFixitFinder : public BfElementVisitor
|
||||
{
|
||||
public:
|
||||
static int FindLineStartAfter(BfSourceData* source, int idx)
|
||||
{
|
||||
bool hadBr = false;
|
||||
while (idx < source->mSrcLength)
|
||||
{
|
||||
char c = source->mSrc[idx];
|
||||
if (c == '\n')
|
||||
{
|
||||
idx++;
|
||||
break;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
static int FindLineStartAfter(BfAstNode* node)
|
||||
{
|
||||
return FindLineStartAfter(node->GetSourceData(), node->GetSrcEnd());
|
||||
}
|
||||
|
||||
static int FindLineStartBefore(BfSourceData* source, int idx)
|
||||
{
|
||||
bool hadBr = false;
|
||||
while (idx >= 0)
|
||||
{
|
||||
char c = source->mSrc[idx];
|
||||
if (c == '\n')
|
||||
{
|
||||
idx++;
|
||||
break;
|
||||
}
|
||||
idx--;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
static int FindLineStartBefore(BfAstNode* node)
|
||||
{
|
||||
return FindLineStartBefore(node->GetSourceData(), node->GetSrcStart());
|
||||
}
|
||||
};
|
||||
|
||||
class BfUsingFinder : public BfFixitFinder
|
||||
{
|
||||
public:
|
||||
int mLastIdx;
|
||||
|
||||
public:
|
||||
BfUsingFinder()
|
||||
{
|
||||
mLastIdx = 0;
|
||||
}
|
||||
virtual void Visit(BfUsingDirective* usingDirective) override
|
||||
{
|
||||
mLastIdx = FindLineStartAfter(usingDirective->GetSourceData(), usingDirective->GetSrcEnd());
|
||||
}
|
||||
};
|
||||
|
||||
NS_BF_END
|
4937
IDEHelper/Compiler/BfIRBuilder.cpp
Normal file
4937
IDEHelper/Compiler/BfIRBuilder.cpp
Normal file
File diff suppressed because it is too large
Load diff
1230
IDEHelper/Compiler/BfIRBuilder.h
Normal file
1230
IDEHelper/Compiler/BfIRBuilder.h
Normal file
File diff suppressed because it is too large
Load diff
4112
IDEHelper/Compiler/BfIRCodeGen.cpp
Normal file
4112
IDEHelper/Compiler/BfIRCodeGen.cpp
Normal file
File diff suppressed because it is too large
Load diff
147
IDEHelper/Compiler/BfIRCodeGen.h
Normal file
147
IDEHelper/Compiler/BfIRCodeGen.h
Normal file
|
@ -0,0 +1,147 @@
|
|||
#pragma once
|
||||
|
||||
#include "BfIRBuilder.h"
|
||||
#include "BfSystem.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
enum BfIRCodeGenEntryKind
|
||||
{
|
||||
BfIRCodeGenEntryKind_None,
|
||||
BfIRCodeGenEntryKind_LLVMValue,
|
||||
BfIRCodeGenEntryKind_LLVMType,
|
||||
BfIRCodeGenEntryKind_LLVMBasicBlock,
|
||||
BfIRCodeGenEntryKind_LLVMMetadata,
|
||||
BfIRCodeGenEntryKind_FakeIntrinsic,
|
||||
};
|
||||
|
||||
struct BfIRCodeGenEntry
|
||||
{
|
||||
BfIRCodeGenEntryKind mKind;
|
||||
union
|
||||
{
|
||||
llvm::Value* mLLVMValue;
|
||||
llvm::Type* mLLVMType;
|
||||
llvm::BasicBlock* mLLVMBlock;
|
||||
llvm::MDNode* mLLVMMetadata;
|
||||
BfIRIntrinsic mIntrinsic;
|
||||
};
|
||||
};
|
||||
|
||||
class BfIRTypeEntry
|
||||
{
|
||||
public:
|
||||
int mTypeId;
|
||||
llvm::DIType* mDIType;
|
||||
llvm::DIType* mInstDIType;
|
||||
llvm::Type* mLLVMType;
|
||||
llvm::Type* mInstLLVMType;
|
||||
|
||||
public:
|
||||
BfIRTypeEntry()
|
||||
{
|
||||
mTypeId = -1;
|
||||
mDIType = NULL;
|
||||
mInstDIType = NULL;
|
||||
mLLVMType = NULL;
|
||||
mInstLLVMType = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
class BfIRCodeGen : public BfIRCodeGenBase
|
||||
{
|
||||
public:
|
||||
BfIRBuilder* mBfIRBuilder;
|
||||
|
||||
String mModuleName;
|
||||
llvm::LLVMContext* mLLVMContext;
|
||||
llvm::Module* mLLVMModule;
|
||||
llvm::Function* mActiveFunction;
|
||||
llvm::IRBuilder<>* mIRBuilder;
|
||||
llvm::AttributeList* mAttrSet;
|
||||
llvm::DIBuilder* mDIBuilder;
|
||||
llvm::DICompileUnit* mDICompileUnit;
|
||||
Array<llvm::DebugLoc> mSavedDebugLocs;
|
||||
llvm::InlineAsm* mNopInlineAsm;
|
||||
llvm::InlineAsm* mAsmObjectCheckAsm;
|
||||
llvm::DebugLoc mDebugLoc;
|
||||
bool mHasDebugLoc;
|
||||
bool mIsCodeView;
|
||||
|
||||
int mCmdCount;
|
||||
Dictionary<int, BfIRCodeGenEntry> mResults;
|
||||
Dictionary<int, BfIRTypeEntry> mTypes;
|
||||
Dictionary<int, llvm::Function*> mIntrinsicMap;
|
||||
Dictionary<llvm::Function*, int> mIntrinsicReverseMap;
|
||||
Array<llvm::Constant*> mConfigConsts32;
|
||||
Array<llvm::Constant*> mConfigConsts64;
|
||||
|
||||
public:
|
||||
BfTypeCode GetTypeCode(llvm::Type* type, bool isSigned);
|
||||
llvm::Type* GetLLVMType(BfTypeCode typeCode, bool& isSigned);
|
||||
BfIRTypeEntry& GetTypeEntry(int typeId);
|
||||
void SetResult(int id, llvm::Value* value);
|
||||
void SetResult(int id, llvm::Type* value);
|
||||
void SetResult(int id, llvm::BasicBlock* value);
|
||||
void SetResult(int id, llvm::MDNode* value);
|
||||
void CreateMemSet(llvm::Value* addr, llvm::Value* val, llvm::Value* size, int alignment, bool isVolatile = false);
|
||||
void AddNop();
|
||||
|
||||
public:
|
||||
BfIRCodeGen();
|
||||
~BfIRCodeGen();
|
||||
|
||||
virtual void Fail(const StringImpl& error) override;
|
||||
|
||||
void ProcessBfIRData(const BfSizedArray<uint8>& buffer) override;
|
||||
void PrintModule();
|
||||
void PrintFunction();
|
||||
|
||||
int64 ReadSLEB128();
|
||||
void Read(StringImpl& str);
|
||||
void Read(int& i);
|
||||
void Read(int64& i);
|
||||
void Read(bool& val);
|
||||
void Read(BfIRTypeEntry*& type);
|
||||
void Read(llvm::Type*& llvmType);
|
||||
void Read(llvm::FunctionType*& llvmType);
|
||||
void Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry = NULL);
|
||||
void Read(llvm::Constant*& llvmConstant);
|
||||
void Read(llvm::Function*& llvmFunc);
|
||||
void Read(llvm::BasicBlock*& llvmBlock);
|
||||
void Read(llvm::MDNode*& llvmMD);
|
||||
void Read(llvm::Metadata*& llvmMD);
|
||||
|
||||
template <typename T>
|
||||
void Read(llvm::SmallVectorImpl<T>& vec)
|
||||
{
|
||||
int len = (int)ReadSLEB128();
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
T result;
|
||||
Read(result);
|
||||
vec.push_back(result);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleNextCmd() override;
|
||||
void SetConfigConst(int idx, int value) override;
|
||||
|
||||
llvm::Value* GetLLVMValue(int streamId);
|
||||
llvm::Type* GetLLVMType(int streamId);
|
||||
llvm::BasicBlock* GetLLVMBlock(int streamId);
|
||||
llvm::MDNode* GetLLVMMetadata(int streamId);
|
||||
|
||||
llvm::Type* GetLLVMTypeById(int id);
|
||||
|
||||
///
|
||||
|
||||
bool WriteObjectFile(const StringImpl& outFileName, const BfCodeGenOptions& codeGenOptions);
|
||||
bool WriteIR(const StringImpl& outFileName, StringImpl& error);
|
||||
|
||||
static int GetIntrinsicId(const StringImpl& name);
|
||||
static const char* GetIntrinsicName(int intrinId);
|
||||
};
|
||||
|
||||
NS_BF_END
|
||||
|
2188
IDEHelper/Compiler/BfMangler.cpp
Normal file
2188
IDEHelper/Compiler/BfMangler.cpp
Normal file
File diff suppressed because it is too large
Load diff
191
IDEHelper/Compiler/BfMangler.h
Normal file
191
IDEHelper/Compiler/BfMangler.h
Normal file
|
@ -0,0 +1,191 @@
|
|||
#pragma once
|
||||
|
||||
#include "BfSystem.h"
|
||||
#include "BeefySysLib/util/SLIList.h"
|
||||
#include "BeefySysLib/util/SizedArray.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
class BfType;
|
||||
class BfFieldInstance;
|
||||
|
||||
class BfMangler
|
||||
{
|
||||
public:
|
||||
enum MangleKind
|
||||
{
|
||||
MangleKind_GNU,
|
||||
MangleKind_Microsoft_32,
|
||||
MangleKind_Microsoft_64
|
||||
};
|
||||
|
||||
struct NameSubstitute
|
||||
{
|
||||
public:
|
||||
enum Kind
|
||||
{
|
||||
Kind_None,
|
||||
Kind_NamespaceAtom,
|
||||
Kind_TypeDefNameAtom,
|
||||
Kind_TypeInstName,
|
||||
Kind_TypeGenericArgs,
|
||||
Kind_MethodName,
|
||||
Kind_Prefix,
|
||||
Kind_PrimitivePrefix,
|
||||
Kind_GenericParam
|
||||
};
|
||||
|
||||
public:
|
||||
union
|
||||
{
|
||||
int mExtendsIdx;
|
||||
int mExtendsTypeId;
|
||||
BfTypeCode mExtendsTypeCode;
|
||||
};
|
||||
Kind mKind;
|
||||
union
|
||||
{
|
||||
void* mParam;
|
||||
|
||||
BfAtom* mAtom;
|
||||
BfTypeDef* mTypeDef;
|
||||
BfType* mType;
|
||||
BfTypeInstance* mTypeInst;
|
||||
BfMethodInstance* mMethodInstance;
|
||||
const char* mPrefix;
|
||||
};
|
||||
|
||||
public:
|
||||
NameSubstitute(Kind kind, void* param)
|
||||
{
|
||||
mExtendsIdx = -1;
|
||||
mKind = kind;
|
||||
mParam = param;
|
||||
}
|
||||
|
||||
NameSubstitute(Kind kind, void* param, int extendsId)
|
||||
{
|
||||
mExtendsIdx = extendsId;
|
||||
mKind = kind;
|
||||
mParam = param;
|
||||
}
|
||||
|
||||
NameSubstitute()
|
||||
{
|
||||
mExtendsIdx = -1;
|
||||
mKind = Kind_None;
|
||||
mParam = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
static void Mangle(StringImpl& outStr, MangleKind mangleKind, BfType* type, BfModule* module = NULL);
|
||||
static void Mangle(StringImpl& outStr, MangleKind mangleKind, BfMethodInstance* methodRef);
|
||||
static void Mangle(StringImpl& outStr, MangleKind mangleKind, BfFieldInstance* fieldInstance);
|
||||
static void MangleMethodName(StringImpl& outStr, MangleKind mangleKind, BfTypeInstance* type, const StringImpl& methodName);
|
||||
static void MangleStaticFieldName(StringImpl& outStr, MangleKind mangleKind, BfTypeInstance* owner, const StringImpl& fieldName, BfType* fieldType = NULL);
|
||||
};
|
||||
|
||||
class BfGNUMangler : public BfMangler
|
||||
{
|
||||
public:
|
||||
class MangleContext
|
||||
{
|
||||
public:
|
||||
BfModule* mModule;
|
||||
bool mCCompat;
|
||||
bool mInArgs;
|
||||
bool mPrefixObjectPointer;
|
||||
llvm::SmallVector<NameSubstitute, 32> mSubstituteList;
|
||||
|
||||
public:
|
||||
MangleContext()
|
||||
{
|
||||
mModule = NULL;
|
||||
mCCompat = false;
|
||||
mInArgs = false;
|
||||
mPrefixObjectPointer = false;
|
||||
}
|
||||
};
|
||||
|
||||
static int ParseSubIdx(StringImpl& name, int strIdx);
|
||||
static void AddSubIdx(StringImpl& name, int strIdx);
|
||||
static void AddSizedString(StringImpl& name, const StringImpl& addStr);
|
||||
static BfTypeCode GetPrimTypeAt(MangleContext& mangleContext, StringImpl& name, int strIdx);
|
||||
static void AddPrefix(MangleContext& mangleContext, StringImpl& name, int startIdx, const char* prefix);
|
||||
static void FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name, const NameSubstitute& newNameSub, int& curMatchIdx, bool& matchFailed);
|
||||
static void FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name, BfTypeInstance* typeInst, int& curMatchIdx, bool& matchFailed);
|
||||
static void FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name, const NameSubstitute& newNameSub);
|
||||
|
||||
public:
|
||||
static void MangleTypeInst(MangleContext& mangleContext, StringImpl& name, BfTypeInstance* typeInst, BfTypeInstance* postfixTypeInst = NULL, bool* isEndOpen = NULL);
|
||||
|
||||
static void Mangle(MangleContext& mangleContext, StringImpl& name, BfType* type, BfType* postfixType = NULL);
|
||||
static String Mangle(BfType* type, BfModule* module = NULL);
|
||||
static String Mangle(BfMethodInstance* methodRef);
|
||||
static String MangleMethodName(BfTypeInstance* type, const StringImpl& methodName);
|
||||
static String MangleStaticFieldName(BfTypeInstance* type, const StringImpl& fieldName);
|
||||
};
|
||||
|
||||
class BfMSMangler : public BfMangler
|
||||
{
|
||||
public:
|
||||
class MangleContext
|
||||
{
|
||||
public:
|
||||
bool mIsSafeMangle;
|
||||
|
||||
BfModule* mModule;
|
||||
bool mCCompat;
|
||||
bool mIs64Bit;
|
||||
SizedArray<NameSubstitute, 10> mSubstituteList;
|
||||
SizedArray<BfType*, 10> mSubstituteTypeList;
|
||||
|
||||
bool mWantsGroupStart;
|
||||
bool mInArgs;
|
||||
bool mInRet;
|
||||
|
||||
public:
|
||||
MangleContext()
|
||||
{
|
||||
mIsSafeMangle = false;
|
||||
mModule = NULL;
|
||||
mCCompat = false;
|
||||
mIs64Bit = false;
|
||||
mWantsGroupStart = false;
|
||||
mInArgs = false;
|
||||
mInRet = false;
|
||||
}
|
||||
|
||||
BfModule* GetUnreifiedModule();
|
||||
};
|
||||
|
||||
static void AddGenericArgs(MangleContext& mangleContext, StringImpl& name, const SizedArrayImpl<BfType*>& genericArgs, int numOuterGenericParams = 0);
|
||||
|
||||
static void AddStr(MangleContext& mangleContext, StringImpl& name, const StringImpl& str);
|
||||
static void Mangle(MangleContext& mangleContext, StringImpl& name, BfType* type, bool useTypeList = false);
|
||||
static void Mangle(MangleContext& mangleContext, StringImpl& name, BfTypeInstance* typeInst, bool isAlreadyStarted, bool isOuterType = false);
|
||||
static void MangleConst(MangleContext& mangleContext, StringImpl& name, int64 val);
|
||||
|
||||
void AddPrefix(MangleContext & mangleContext, StringImpl& name, int startIdx, const char * prefix);
|
||||
|
||||
static void AddSubIdx(StringImpl& name, int strIdx);
|
||||
static void AddTypeStart(MangleContext & mangleContext, StringImpl& name, BfType* type);
|
||||
static bool FindOrCreateNameSub(MangleContext& mangleContext, StringImpl& name, const NameSubstitute& newNameSub);
|
||||
|
||||
public:
|
||||
static void Mangle(StringImpl& outStr, bool is64Bit, BfType* type, BfModule* module = NULL);
|
||||
static void Mangle(StringImpl& outStr, bool is64Bit, BfMethodInstance* methodRef);
|
||||
static void Mangle(StringImpl& outStr, bool is64Bit, BfFieldInstance* fieldInstance);
|
||||
static void MangleMethodName(StringImpl& outStr, bool is64Bit, BfTypeInstance* type, const StringImpl& methodName);
|
||||
static void MangleStaticFieldName(StringImpl& outStr, bool is64Bit, BfTypeInstance* type, const StringImpl& fieldName, BfType* fieldType = NULL);
|
||||
};
|
||||
|
||||
// A "safe mangle" is used for reconnecting deleted types to their previous id. We make sure we never force a
|
||||
// PopulateType with this kind of mangle, as referenced types may be deleted and marked as undefined
|
||||
class BfSafeMangler : public BfMSMangler
|
||||
{
|
||||
public:
|
||||
static String Mangle(BfType* type, BfModule* module = NULL);
|
||||
};
|
||||
|
||||
NS_BF_END
|
20657
IDEHelper/Compiler/BfModule.cpp
Normal file
20657
IDEHelper/Compiler/BfModule.cpp
Normal file
File diff suppressed because it is too large
Load diff
1813
IDEHelper/Compiler/BfModule.h
Normal file
1813
IDEHelper/Compiler/BfModule.h
Normal file
File diff suppressed because it is too large
Load diff
10622
IDEHelper/Compiler/BfModuleTypeUtils.cpp
Normal file
10622
IDEHelper/Compiler/BfModuleTypeUtils.cpp
Normal file
File diff suppressed because it is too large
Load diff
3591
IDEHelper/Compiler/BfParser.cpp
Normal file
3591
IDEHelper/Compiler/BfParser.cpp
Normal file
File diff suppressed because it is too large
Load diff
260
IDEHelper/Compiler/BfParser.h
Normal file
260
IDEHelper/Compiler/BfParser.h
Normal file
|
@ -0,0 +1,260 @@
|
|||
#pragma once
|
||||
|
||||
#include "BeefySysLib/Common.h"
|
||||
#include "BfAst.h"
|
||||
#include "BeefySysLib/util/BumpAllocator.h"
|
||||
#include "BeefySysLib/util/Hash.h"
|
||||
#include "BeefySysLib/util/HashSet.h"
|
||||
#include "BfUtil.h"
|
||||
#include "BfSource.h"
|
||||
#include "MemReporter.h"
|
||||
#include <set>
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
class BfPassInstance;
|
||||
class BfProject;
|
||||
|
||||
enum BfSyntaxToken
|
||||
{
|
||||
BfSyntaxToken_Token,
|
||||
BfSyntaxToken_Identifier,
|
||||
BfSyntaxToken_CharQuote,
|
||||
BfSyntaxToken_StringQuote,
|
||||
BfSyntaxToken_ForwardSlash,
|
||||
BfSyntaxToken_Literal,
|
||||
BfSyntaxToken_CommentLine,
|
||||
BfSyntaxToken_CommentBlock,
|
||||
BfSyntaxToken_FAILED,
|
||||
BfSyntaxToken_HIT_END_IDX,
|
||||
BfSyntaxToken_EOF
|
||||
};
|
||||
|
||||
struct BfLineStartEntry
|
||||
{
|
||||
int mCharIdx;
|
||||
int mLineNum;
|
||||
};
|
||||
|
||||
#define PARSER_JUMPTABLE_DIVIDE 64
|
||||
|
||||
enum BfParserFlag
|
||||
{
|
||||
ParserFlag_None,
|
||||
ParserFlag_Autocomplete = 1,
|
||||
ParserFlag_GetDefinition = 2,
|
||||
ParserFlag_Classifying = 4,
|
||||
};
|
||||
|
||||
struct BfParserWarningEnabledChange
|
||||
{
|
||||
int mWarningNumber;
|
||||
bool mEnable;
|
||||
};
|
||||
|
||||
enum MaybeBool
|
||||
{
|
||||
MaybeBool_None = -1,
|
||||
MaybeBool_False = 0,
|
||||
MaybeBool_True = 1,
|
||||
};
|
||||
|
||||
class BfParserData : public BfSourceData
|
||||
{
|
||||
public:
|
||||
uint64 mHash;
|
||||
int mDataId;
|
||||
int mRefCount; // -1 = not cached
|
||||
BfParser* mUniqueParser; // For non-cached usage (ie: autocomplete)
|
||||
String mFileName;
|
||||
uint8* mCharIdData;
|
||||
|
||||
HashSet<String> mDefines_Def;
|
||||
HashSet<String> mDefines_NoDef;
|
||||
|
||||
BfLineStartEntry* mJumpTable;
|
||||
int mJumpTableSize;
|
||||
OwnedVector<String> mStringLiterals;
|
||||
Dictionary<int, BfParserWarningEnabledChange> mWarningEnabledChanges;
|
||||
std::set<int> mUnwarns;
|
||||
bool mFailed; // Don't cache if there's a warning or an error
|
||||
bool mDidReduce;
|
||||
|
||||
public:
|
||||
BfParserData();
|
||||
~BfParserData();
|
||||
void Deref();
|
||||
|
||||
virtual BfParserData* ToParserData() override
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
virtual BfParser* ToParser() override;
|
||||
int GetCharIdAtIndex(int findIndex);
|
||||
void GetLineCharAtIdx(int idx, int& line, int& lineChar);
|
||||
bool IsUnwarnedAt(BfAstNode* node);
|
||||
bool IsWarningEnabledAtSrcIndex(int warningNumber, int srcIdx);
|
||||
void ReportMemory(MemReporter* memReporter);
|
||||
};
|
||||
|
||||
class BfParserCache
|
||||
{
|
||||
public:
|
||||
struct LookupEntry
|
||||
{
|
||||
uint64 mHash;
|
||||
String mFileName;
|
||||
const char* mSrc;
|
||||
int mSrcLength;
|
||||
BfProject* mProject;
|
||||
};
|
||||
|
||||
struct DataEntry
|
||||
{
|
||||
BfParserData* mParserData;
|
||||
|
||||
bool operator==(const LookupEntry& lookup) const;
|
||||
bool operator==(const DataEntry& lookup) const
|
||||
{
|
||||
return lookup.mParserData == mParserData;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
CritSect mCritSect;
|
||||
int mRefCount;
|
||||
BfAstAllocManager mAstAllocManager;
|
||||
HashSet<DataEntry> mEntries;
|
||||
|
||||
public:
|
||||
BfParserCache();
|
||||
~BfParserCache();
|
||||
void ReportMemory(MemReporter* memReporter);
|
||||
};
|
||||
|
||||
enum BfDefineState
|
||||
{
|
||||
BfDefineState_FromProject,
|
||||
BfDefineState_ManualSet,
|
||||
BfDefineState_ManualUnset
|
||||
};
|
||||
|
||||
class BfParser : public BfSource
|
||||
{
|
||||
public:
|
||||
BfParserData* mParserData;
|
||||
bool mUsingCache;
|
||||
|
||||
BfPassInstance* mPassInstance;
|
||||
String mFileName;
|
||||
bool mAwaitingDelete;
|
||||
|
||||
bool mCompatMode; // Does C++ compatible parsing
|
||||
bool mQuickCompatMode;
|
||||
bool mScanOnly;
|
||||
bool mCompleteParse;
|
||||
BfLineStartEntry* mJumpTable;
|
||||
int mJumpTableSize;
|
||||
int mOrigSrcLength;
|
||||
int mDataId;
|
||||
|
||||
int mSrcIdx;
|
||||
int mLineStart;
|
||||
int mLineNum;
|
||||
bool mInAsmBlock;
|
||||
|
||||
BfParserFlag mParserFlags;
|
||||
int mCursorIdx;
|
||||
int mCursorCheckIdx;
|
||||
|
||||
BfSyntaxToken mSyntaxToken;
|
||||
int mTriviaStart; // mTriviaStart < mTokenStart when there's leading whitespace
|
||||
int mTokenStart;
|
||||
int mTokenEnd;
|
||||
BfVariant mLiteral;
|
||||
BfToken mToken;
|
||||
BfPreprocesorIgnoredSectionNode* mPreprocessorIgnoredSectionNode;
|
||||
int mPreprocessorIgnoreDepth;
|
||||
Array< std::pair<BfAstNode*, bool> > mPreprocessorNodeStack;
|
||||
|
||||
Dictionary<String, BfDefineState> mPreprocessorDefines;
|
||||
|
||||
std::set<int> mPreprocessorIgnoredSectionStarts;
|
||||
|
||||
public:
|
||||
virtual void HandleInclude(BfAstNode* paramNode);
|
||||
virtual void HandleIncludeNext(BfAstNode* paramNode);
|
||||
virtual void HandlePragma(const StringImpl& pragma, BfBlock* block);
|
||||
virtual void HandleDefine(const StringImpl& name, BfAstNode* paramNode);
|
||||
virtual void HandleUndefine(const StringImpl& name);
|
||||
virtual MaybeBool HandleIfDef(const StringImpl& name);
|
||||
virtual MaybeBool HandleProcessorCondition(BfBlock* paramNode);
|
||||
|
||||
public:
|
||||
void Init(uint64 cacheHash = 0);
|
||||
void NewLine();
|
||||
BfExpression* CreateInlineExpressionFromNode(BfBlock* block);
|
||||
bool EvaluatePreprocessor(BfExpression* expr);
|
||||
BfBlock* ParseInlineBlock(int spaceIdx, int endIdx);
|
||||
void HandlePreprocessor();
|
||||
bool IsUnwarnedAt(BfAstNode* node);
|
||||
bool SrcPtrHasToken(const char* name);
|
||||
uint32 GetTokenHash();
|
||||
void ParseBlock(BfBlock* astNode, int depth);
|
||||
double ParseLiteralDouble();
|
||||
void AddErrorNode(int startIdx, int endIdx);
|
||||
BfCommentKind GetCommentKind(int startIdx);
|
||||
|
||||
public:
|
||||
BfParser(BfSystem* bfSystem, BfProject* bfProject = NULL);
|
||||
~BfParser();
|
||||
|
||||
void SetCursorIdx(int cursorIdx);
|
||||
virtual BfParser* ToParser() override { return this; }
|
||||
|
||||
void GetLineCharAtIdx(int idx, int& line, int& lineChar);
|
||||
|
||||
void Fail(const StringImpl& error, int offset = -1);
|
||||
void TokenFail(const StringImpl& error, int offset = -1);
|
||||
|
||||
void SetSource(const char* data, int length);
|
||||
void MoveSource(const char* data, int length); // Takes ownership of data ptr
|
||||
void RefSource(const char* data, int length);
|
||||
void NextToken(int endIdx = -1);
|
||||
BfAstNode* CreateNode();
|
||||
|
||||
void Parse(BfPassInstance* passInstance);
|
||||
int GetCharIdAtIndex(int findIndex);
|
||||
virtual void Close() override;
|
||||
|
||||
void GenerateAutoCompleteFrom(int srcPosition);
|
||||
|
||||
void ReportMemory(MemReporter* memReporter);
|
||||
void GetSrcPosition(int idx, int& lineNum, int& column);
|
||||
};
|
||||
|
||||
extern BfParserCache* gBfParserCache;
|
||||
|
||||
NS_BF_END
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<>
|
||||
struct hash<Beefy::BfParserCache::LookupEntry>
|
||||
{
|
||||
size_t operator()(const Beefy::BfParserCache::LookupEntry& val) const
|
||||
{
|
||||
return (size_t)val.mHash;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<Beefy::BfParserCache::DataEntry>
|
||||
{
|
||||
size_t operator()(const Beefy::BfParserCache::DataEntry& val) const
|
||||
{
|
||||
return (size_t)val.mParserData->mHash;
|
||||
}
|
||||
};
|
||||
}
|
2451
IDEHelper/Compiler/BfPrinter.cpp
Normal file
2451
IDEHelper/Compiler/BfPrinter.cpp
Normal file
File diff suppressed because it is too large
Load diff
207
IDEHelper/Compiler/BfPrinter.h
Normal file
207
IDEHelper/Compiler/BfPrinter.h
Normal file
|
@ -0,0 +1,207 @@
|
|||
#include "BeefySysLib/Common.h"
|
||||
//#include "llvm/Support/raw_ostream.h"
|
||||
#include "BfAst.h"
|
||||
#include "BfElementVisitor.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
|
||||
class BfPrinter : public BfElementVisitor
|
||||
{
|
||||
public:
|
||||
struct StateModify
|
||||
{
|
||||
public:
|
||||
bool mExpectingSpace;
|
||||
int mWantNewLineIdx;
|
||||
bool mDoingBlockOpen;
|
||||
bool mDoingBlockClose;
|
||||
int mWantVirtualIndent;
|
||||
BfAstNode* mQueuedNode;
|
||||
|
||||
public:
|
||||
StateModify()
|
||||
{
|
||||
Clear();
|
||||
mWantVirtualIndent = 0;
|
||||
mWantNewLineIdx = 0;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
mExpectingSpace = false;
|
||||
mDoingBlockOpen = false;
|
||||
mDoingBlockClose = false;
|
||||
mQueuedNode = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
BfSourceData* mSource;
|
||||
BfParserData* mParser;
|
||||
|
||||
BfBlock::Iterator mSidechannelItr;
|
||||
BfAstNode* mSidechannelNextNode;
|
||||
|
||||
BfBlock::Iterator mErrorItr;
|
||||
BfAstNode* mErrorNextNode;
|
||||
BfAstNode* mCurBlockMember;
|
||||
BfTypeDeclaration* mCurTypeDecl;
|
||||
|
||||
int mTriviaIdx;
|
||||
int mCurSrcIdx;
|
||||
Array<StateModify> mChildNodeQueue;
|
||||
int mFormatStart;
|
||||
int mFormatEnd;
|
||||
StateModify mNextStateModify;
|
||||
|
||||
String mOutString;
|
||||
bool mReformatting;
|
||||
bool mIgnoreTrivia;
|
||||
bool mDocPrep;
|
||||
int mCurIndentLevel;
|
||||
int mQueuedSpaceCount;
|
||||
int mLastSpaceOffset; // Indent difference from original to new
|
||||
bool mExpectingNewLine;
|
||||
|
||||
bool mIsFirstStatementInBlock;
|
||||
bool mForceUseTrivia;
|
||||
bool mInSideChannel;
|
||||
|
||||
int mStateModifyVirtualIndentLevel;
|
||||
int mVirtualIndentLevel;
|
||||
int mVirtualNewLineIdx;
|
||||
|
||||
Array<int>* mCharMapping;
|
||||
int mHighestCharId;
|
||||
|
||||
public:
|
||||
BfPrinter(BfRootNode* rootNode, BfRootNode* sidechannelRootNode, BfRootNode* errorRootNode);
|
||||
|
||||
public:
|
||||
bool CheckReplace(BfAstNode* astNode);
|
||||
void FlushIndent();
|
||||
void Write(const StringImpl& str);
|
||||
void Write(BfAstNode* node, int start, int len);
|
||||
void WriteSourceString(BfAstNode* node);
|
||||
void QueueVisitChild(BfAstNode* astNode);
|
||||
void QueueVisitErrorNodes(BfRootNode* astNode);
|
||||
void FlushVisitChild();
|
||||
void VisitChildWithPrecedingSpace(BfAstNode* bfAstNode);
|
||||
void VisitChildWithProceedingSpace(BfAstNode* bfAstNode);
|
||||
void ExpectSpace();
|
||||
void ExpectNewLine();
|
||||
void ExpectIndent();
|
||||
void ExpectUnindent();
|
||||
void VisitChildNextLine(BfAstNode* node);
|
||||
void DoBlockOpen(BfBlock* block, bool queue, bool* outDoInlineBlock);
|
||||
void DoBlockClose(BfBlock* block, bool queue, bool doInlineBlock);
|
||||
void QueueMethodDeclaration(BfMethodDeclaration* methodDeclaration);
|
||||
int CalcOrigLineSpacing(BfAstNode* bfAstNode, int* lineStartIdx);
|
||||
void WriteIgnoredNode(BfAstNode* node);
|
||||
|
||||
virtual void Visit(BfAstNode* bfAstNode) override;
|
||||
virtual void Visit(BfErrorNode* bfErrorNode) override;
|
||||
virtual void Visit(BfExpression* expr) override;
|
||||
virtual void Visit(BfExpressionStatement* exprStmt) override;
|
||||
virtual void Visit(BfAttributedExpression* attribExpr) override;
|
||||
virtual void Visit(BfStatement* stmt) override;
|
||||
virtual void Visit(BfLabelableStatement* labelableStmt) override;
|
||||
|
||||
virtual void Visit(BfCommentNode* commentNode) override;
|
||||
virtual void Visit(BfPreprocesorIgnoredSectionNode* preprocesorIgnoredSection) override;
|
||||
virtual void Visit(BfPreprocessorNode* preprocessorNode) override;
|
||||
|
||||
virtual void Visit(BfAttributeDirective* attributeDirective) override;
|
||||
virtual void Visit(BfGenericParamsDeclaration* genericParams) override;
|
||||
virtual void Visit(BfGenericConstraintsDeclaration* genericConstraints) override;
|
||||
virtual void Visit(BfGenericArgumentsNode* genericArgumentsNode) override;
|
||||
|
||||
virtual void Visit(BfEmptyStatement* emptyStmt) override;
|
||||
virtual void Visit(BfTokenNode* tokenNode) override;
|
||||
virtual void Visit(BfLiteralExpression* literalExpr) override;
|
||||
virtual void Visit(BfIdentifierNode* identifierNode) override;
|
||||
virtual void Visit(BfQualifiedNameNode* nameNode) override;
|
||||
virtual void Visit(BfThisExpression* thisExpr) override;
|
||||
virtual void Visit(BfBaseExpression* baseExpr) override;
|
||||
virtual void Visit(BfMixinExpression* mixinExpr) override;
|
||||
virtual void Visit(BfSizedArrayCreateExpression* createExpr) override;
|
||||
virtual void Visit(BfCollectionInitializerExpression* initExpr) override;
|
||||
virtual void Visit(BfArraySizeSpecifier* arraySizeSpecifier) override;
|
||||
virtual void Visit(BfTypeReference* typeRef) override;
|
||||
virtual void Visit(BfNamedTypeReference* typeRef) override;
|
||||
virtual void Visit(BfQualifiedTypeReference* qualifiedType) override;
|
||||
virtual void Visit(BfVarTypeReference* typeRef) override;
|
||||
virtual void Visit(BfLetTypeReference * typeRef) override;
|
||||
virtual void Visit(BfConstTypeRef* typeRef) override;
|
||||
virtual void Visit(BfConstExprTypeRef* typeRef) override;
|
||||
virtual void Visit(BfRefTypeRef* typeRef) override;
|
||||
virtual void Visit(BfArrayTypeRef* typeRef) override;
|
||||
virtual void Visit(BfGenericInstanceTypeRef* typeRef) override;
|
||||
virtual void Visit(BfTupleTypeRef * typeRef) override;
|
||||
virtual void Visit(BfPointerTypeRef* typeRef) override;
|
||||
virtual void Visit(BfNullableTypeRef* typeRef) override;
|
||||
virtual void Visit(BfVariableDeclaration* varDecl) override;
|
||||
virtual void Visit(BfParameterDeclaration* paramDecl) override;
|
||||
virtual void Visit(BfParamsExpression* paramsExpr) override;
|
||||
virtual void Visit(BfTypeOfExpression* typeOfExpr) override;
|
||||
virtual void Visit(BfSizeOfExpression* sizeOfExpr) override;
|
||||
virtual void Visit(BfDefaultExpression* defaultExpr) override;
|
||||
virtual void Visit(BfCheckTypeExpression* checkTypeExpr) override;
|
||||
virtual void Visit(BfDynamicCastExpression* dynCastExpr) override;
|
||||
virtual void Visit(BfCastExpression* castExpr) override;
|
||||
virtual void Visit(BfDelegateBindExpression* invocationExpr) override;
|
||||
virtual void Visit(BfLambdaBindExpression* lambdaBindExpr);
|
||||
virtual void Visit(BfObjectCreateExpression* invocationExpr) override;
|
||||
virtual void Visit(BfBoxExpression* boxExpr) override;
|
||||
virtual void Visit(BfInvocationExpression* invocationExpr) override;
|
||||
virtual void Visit(BfSwitchCase* switchCase) override;
|
||||
virtual void Visit(BfWhenExpression* whenExpr) override;
|
||||
virtual void Visit(BfSwitchStatement* switchStmt) override;
|
||||
virtual void Visit(BfTryStatement* tryStmt) override;
|
||||
virtual void Visit(BfCatchStatement* catchStmt) override;
|
||||
virtual void Visit(BfFinallyStatement* finallyStmt) override;
|
||||
virtual void Visit(BfCheckedStatement* checkedStmt) override;
|
||||
virtual void Visit(BfUncheckedStatement* uncheckedStmt) override;
|
||||
virtual void Visit(BfIfStatement* ifStmt) override;
|
||||
virtual void Visit(BfThrowStatement* throwStmt) override;
|
||||
virtual void Visit(BfDeleteStatement* deleteStmt) override;
|
||||
virtual void Visit(BfReturnStatement* returnStmt) override;
|
||||
virtual void Visit(BfBreakStatement* breakStmt) override;
|
||||
virtual void Visit(BfContinueStatement* continueStmt) override;
|
||||
virtual void Visit(BfFallthroughStatement* fallthroughStmt) override;
|
||||
virtual void Visit(BfUsingStatement* whileStmt) override;
|
||||
virtual void Visit(BfDoStatement* whileStmt) override;
|
||||
virtual void Visit(BfRepeatStatement* repeatStmt) override;
|
||||
virtual void Visit(BfWhileStatement* whileStmt) override;
|
||||
virtual void Visit(BfForStatement* forStmt) override;
|
||||
virtual void Visit(BfForEachStatement* forEachStmt) override;
|
||||
virtual void Visit(BfDeferStatement* deferStmt) override;
|
||||
virtual void Visit(BfEnumCaseBindExpression * caseBindExpr) override;
|
||||
virtual void Visit(BfCaseExpression * caseExpr) override;
|
||||
virtual void Visit(BfConditionalExpression* condExpr) override;
|
||||
virtual void Visit(BfAssignmentExpression* assignExpr) override;
|
||||
virtual void Visit(BfParenthesizedExpression* parenExpr) override;
|
||||
virtual void Visit(BfTupleExpression * tupleExpr) override;
|
||||
virtual void Visit(BfMemberReferenceExpression* memberRefExpr) override;
|
||||
virtual void Visit(BfIndexerExpression* indexerExpr) override;
|
||||
virtual void Visit(BfUnaryOperatorExpression* binOpExpr) override;
|
||||
virtual void Visit(BfBinaryOperatorExpression* binOpExpr) override;
|
||||
virtual void Visit(BfConstructorDeclaration* ctorDeclaration) override;
|
||||
virtual void Visit(BfDestructorDeclaration* dtorDeclaration) override;
|
||||
virtual void Visit(BfMethodDeclaration* methodDeclaration) override;
|
||||
virtual void Visit(BfOperatorDeclaration* opreratorDeclaration) override;
|
||||
virtual void Visit(BfPropertyMethodDeclaration* propertyDeclaration) override;
|
||||
virtual void Visit(BfPropertyDeclaration* propertyDeclaration) override;
|
||||
virtual void Visit(BfFieldDeclaration* fieldDeclaration) override;
|
||||
virtual void Visit(BfEnumCaseDeclaration* enumCaseDeclaration) override;
|
||||
virtual void Visit(BfTypeAliasDeclaration* typeDeclaration) override;
|
||||
virtual void Visit(BfTypeDeclaration* typeDeclaration) override;
|
||||
virtual void Visit(BfUsingDirective* usingDirective) override;
|
||||
virtual void Visit(BfUsingStaticDirective* usingDirective) override;
|
||||
virtual void Visit(BfNamespaceDeclaration* namespaceDeclaration) override;
|
||||
virtual void Visit(BfBlock* block) override;
|
||||
virtual void Visit(BfRootNode* rootNode) override;
|
||||
virtual void Visit(BfInlineAsmStatement* asmStmt) override;
|
||||
};
|
||||
|
||||
NS_BF_END
|
9773
IDEHelper/Compiler/BfReducer.cpp
Normal file
9773
IDEHelper/Compiler/BfReducer.cpp
Normal file
File diff suppressed because it is too large
Load diff
234
IDEHelper/Compiler/BfReducer.h
Normal file
234
IDEHelper/Compiler/BfReducer.h
Normal file
|
@ -0,0 +1,234 @@
|
|||
#pragma once
|
||||
|
||||
#include "BeefySysLib/Common.h"
|
||||
#include "BfAst.h"
|
||||
#include "BfType.h"
|
||||
#include "BeefySysLib/util/BumpAllocator.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
class BfPassInstance;
|
||||
class BfResolvePassData;
|
||||
|
||||
class BfReducer
|
||||
{
|
||||
public:
|
||||
enum CreateExprFlags
|
||||
{
|
||||
CreateExprFlags_None,
|
||||
CreateExprFlags_NoCaseExpr = 1,
|
||||
CreateExprFlags_NoAssignment = 2,
|
||||
CreateExprFlags_AllowVariableDecl = 4,
|
||||
CreateExprFlags_PermissiveVariableDecl = 8,
|
||||
CreateExprFlags_NoCast = 0x10,
|
||||
CreateExprFlags_BreakOnRChevron = 0x20,
|
||||
CreateExprFlags_ExitOnBang = 0x40,
|
||||
CreateExprFlags_ExitOnParenExpr = 0x80,
|
||||
CreateExprFlags_NoCheckBinOpPrecedence = 0x100,
|
||||
CreateExprFlags_BreakOnCascade = 0x200
|
||||
};
|
||||
|
||||
enum CreateStmtFlags
|
||||
{
|
||||
CreateStmtFlags_None,
|
||||
CreateStmtFlags_NoCaseExpr = 1,
|
||||
CreateStmtFlags_FindTrailingSemicolon = 2,
|
||||
CreateStmtFlags_AllowUnterminatedExpression = 4,
|
||||
CreateStmtFlags_AllowLocalFunction = 8,
|
||||
CreateStmtFlags_ForceVariableDecl = 0x10,
|
||||
|
||||
CreateStmtFlags_To_CreateExprFlags_Mask = 1
|
||||
};
|
||||
|
||||
struct BfVisitorPos
|
||||
{
|
||||
BfBlock* mParent;
|
||||
int mReadPos;
|
||||
int mWritePos;
|
||||
int mTotalSize;
|
||||
|
||||
BfVisitorPos(BfBlock* parent = NULL)
|
||||
{
|
||||
mParent = parent;
|
||||
mReadPos = -1;
|
||||
mWritePos = 0;
|
||||
if (parent != NULL)
|
||||
mTotalSize = parent->GetSize();
|
||||
else
|
||||
mTotalSize = 0;
|
||||
}
|
||||
|
||||
bool MoveNext()
|
||||
{
|
||||
mReadPos++;
|
||||
return mReadPos < mTotalSize;
|
||||
}
|
||||
|
||||
BfAstNode* GetCurrent()
|
||||
{
|
||||
if ((uint)mReadPos >= (uint)mTotalSize)
|
||||
return NULL;
|
||||
return (*mParent)[mReadPos];
|
||||
}
|
||||
|
||||
BfAstNode* Get(int idx)
|
||||
{
|
||||
if (((uint)idx >= (uint)mTotalSize))
|
||||
return NULL;
|
||||
return (*mParent)[idx];
|
||||
}
|
||||
|
||||
void Set(int idx, BfAstNode* node)
|
||||
{
|
||||
if (((uint)idx >= (uint)mTotalSize))
|
||||
return;
|
||||
(*mParent)[idx] = node;
|
||||
}
|
||||
|
||||
void ReplaceCurrent(BfAstNode* node)
|
||||
{
|
||||
if ((uint)mReadPos >= (uint)mTotalSize)
|
||||
return;
|
||||
(*mParent)[mReadPos] = node;
|
||||
}
|
||||
|
||||
void Write(BfAstNode* node)
|
||||
{
|
||||
(*mParent)[mWritePos++] = node;
|
||||
BF_ASSERT(mWritePos <= mReadPos);
|
||||
}
|
||||
|
||||
BfAstNode* GetNext()
|
||||
{
|
||||
if ((uint)(mReadPos + 1) >= (uint)(mTotalSize))
|
||||
return NULL;
|
||||
return (*mParent)[mReadPos + 1];
|
||||
}
|
||||
|
||||
int GetReadNodesLeft()
|
||||
{
|
||||
return std::max(0, mTotalSize - mReadPos);
|
||||
}
|
||||
|
||||
void Trim()
|
||||
{
|
||||
mParent->SetSize(mWritePos);
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
BfAstAllocator* mAlloc;
|
||||
BfSystem* mSystem;
|
||||
BfSource* mSource;
|
||||
BfPassInstance* mPassInstance;
|
||||
BfResolvePassData* mResolvePassData;
|
||||
BfAstNode* mTypeMemberNodeStart;
|
||||
int mClassDepth;
|
||||
int mMethodDepth;
|
||||
BfTypeDeclaration* mCurTypeDecl;
|
||||
BfTypeDeclaration* mLastTypeDecl;
|
||||
BfMethodDeclaration* mCurMethodDecl;
|
||||
bool mStmtHasError;
|
||||
bool mPrevStmtHadError;
|
||||
bool mCompatMode; // Does C++ compatible parsing
|
||||
bool mAllowTypeWildcard;
|
||||
bool mIsFieldInitializer;
|
||||
bool mInParenExpr;
|
||||
bool mSkipCurrentNodeAssert;
|
||||
BfVisitorPos mVisitorPos;
|
||||
int mDocumentCheckIdx;
|
||||
SizedArray<BfAstNode*, 4> mExteriorNodes;
|
||||
|
||||
int mAssertCurrentNodeIdx;
|
||||
|
||||
public:
|
||||
BfAstNode* Fail(const StringImpl& errorMsg, BfAstNode* refNode);
|
||||
BfAstNode* FailAfter(const StringImpl& errorMsg, BfAstNode* refNode);
|
||||
void AddErrorNode(BfAstNode* astNode, bool removeNode = true);
|
||||
|
||||
public:
|
||||
bool StringEquals(BfAstNode* node, BfAstNode* node2);
|
||||
bool IsSemicolon(BfAstNode* node);
|
||||
BfTokenNode* ExpectTokenAfter(BfAstNode* node, BfToken token);
|
||||
BfTokenNode* ExpectTokenAfter(BfAstNode* node, BfToken tokenA, BfToken tokenB);
|
||||
BfTokenNode* ExpectTokenAfter(BfAstNode* node, BfToken tokenA, BfToken tokenB, BfToken tokenC);
|
||||
BfTokenNode* ExpectTokenAfter(BfAstNode* node, BfToken tokenA, BfToken tokenB, BfToken tokenC, BfToken tokenD);
|
||||
BfIdentifierNode* ExpectIdentifierAfter(BfAstNode* node, const char* typeName = NULL);
|
||||
BfBlock* ExpectBlockAfter(BfAstNode* node);
|
||||
BfTokenNode* BreakDoubleChevron(BfTokenNode* tokenNode);
|
||||
BfTokenNode* BreakQuestionLBracket(BfTokenNode* tokenNode);
|
||||
BfCommentNode* FindDocumentation(BfAstNode* defNodeHead, BfAstNode* defNodeEnd = NULL, bool checkDocAfter = false);
|
||||
|
||||
void AssertCurrentNode(BfAstNode* node);
|
||||
bool IsNodeRelevant(BfAstNode* astNode);
|
||||
bool IsNodeRelevant(BfAstNode* startNode, BfAstNode* endNode);
|
||||
void MoveNode(BfAstNode* srcNode, BfAstNode* newOwner);
|
||||
void ReplaceNode(BfAstNode* prevNode, BfAstNode* newNode);
|
||||
|
||||
BfAstNode* CreateAllocNode(BfTokenNode* newNode);
|
||||
BfAstNode* ReplaceTokenStarter(BfAstNode* astNode, int idx = -1);
|
||||
BfEnumCaseBindExpression* CreateEnumCaseBindExpression(BfTokenNode* bindToken);
|
||||
BfExpression* CheckBinaryOperatorPrecedence(BfBinaryOperatorExpression* binOpExpression);
|
||||
BfExpression* ApplyToFirstExpression(BfUnaryOperatorExpression* unaryOp, BfExpression* target);
|
||||
BfIdentifierNode* ExtractExplicitInterfaceRef(BfAstNode* memberDeclaration, BfIdentifierNode* nameIdentifier, BfTypeReference** outExplicitInterface, BfTokenNode** outExplicitInterfaceDotToken);
|
||||
BfTokenNode* ParseMethodParams(BfAstNode* node, SizedArrayImpl<BfParameterDeclaration*>* params, SizedArrayImpl<BfTokenNode*>* commas, BfToken endToken);
|
||||
BfTokenNode* ReadArguments(BfAstNode* parentNode, BfAstNode* afterNode, SizedArrayImpl<BfExpression*>* arguments, SizedArrayImpl<BfTokenNode*>* commas, BfToken endToken, bool allowSkippedArgs = false, CreateExprFlags createExprFlags = CreateExprFlags_None);
|
||||
void ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, BfBlock* block);
|
||||
BfAstNode* ReadTypeMember(BfTokenNode* node, int depth = 0);
|
||||
BfAstNode* ReadTypeMember(BfAstNode* node, int depth = 0);
|
||||
BfIdentifierNode* CompactQualifiedName(BfAstNode* leftNode);
|
||||
void CreateQualifiedNames(BfAstNode* node);
|
||||
BfFieldDtorDeclaration* CreateFieldDtorDeclaration(BfAstNode* srcNode);
|
||||
BfFieldDeclaration* CreateFieldDeclaration(BfTokenNode* tokenNode, BfTypeReference* typeRef, BfIdentifierNode* nameIdentifier, BfFieldDeclaration* prevFieldDeclaration);
|
||||
BfAttributeDirective* CreateAttributeDirective(BfTokenNode* startToken);
|
||||
BfExpression* CreateAttributedExpression(BfTokenNode* tokenNode, bool onlyAllowIdentifier);
|
||||
BfDelegateBindExpression* CreateDelegateBindExpression(BfAstNode* allocNode);
|
||||
BfLambdaBindExpression* CreateLambdaBindExpression(BfAstNode* allocNode, BfTokenNode* parenToken = NULL);
|
||||
BfCollectionInitializerExpression* CreateCollectionInitializerExpression(BfBlock* block);
|
||||
BfCollectionInitializerExpression* CreateCollectionInitializerExpression(BfTokenNode* openToken);
|
||||
BfObjectCreateExpression* CreateObjectCreateExpression(BfAstNode* allocNode);
|
||||
BfScopedInvocationTarget* CreateScopedInvocationTarget(BfAstNode*& targetRef, BfTokenNode* colonToken);
|
||||
BfInvocationExpression* CreateInvocationExpression(BfAstNode* target, CreateExprFlags createExprFlags = CreateExprFlags_None);
|
||||
BfExpression* CreateIndexerExpression(BfExpression* target);
|
||||
BfMemberReferenceExpression* CreateMemberReferenceExpression(BfAstNode* target);
|
||||
BfTupleExpression* CreateTupleExpression(BfTokenNode* newNode, BfExpression* innerExpr = NULL);
|
||||
BfExpression* CreateExpression(BfAstNode* node, CreateExprFlags createExprFlags = CreateExprFlags_None);
|
||||
BfExpression* CreateExpressionAfter(BfAstNode* node, CreateExprFlags createExprFlags = CreateExprFlags_None);
|
||||
BfSwitchStatement* CreateSwitchStatement(BfTokenNode* tokenNode);
|
||||
BfAstNode* DoCreateStatement(BfAstNode* node, CreateStmtFlags createStmtFlags = CreateStmtFlags_None);
|
||||
bool IsTerminatingExpression(BfAstNode * node);
|
||||
BfAstNode* CreateStatement(BfAstNode* node, CreateStmtFlags createStmtFlags = CreateStmtFlags_None);
|
||||
BfAstNode* CreateStatementAfter(BfAstNode* node, CreateStmtFlags createStmtFlags = CreateStmtFlags_None);
|
||||
bool IsExtendedTypeName(BfIdentifierNode* identifierNode);
|
||||
bool IsTypeReference(BfAstNode* checkNode, BfToken successToken, int* outEndNode = NULL, bool* couldBeExpr = NULL, bool* isGenericType = NULL, bool* isTuple = NULL);
|
||||
bool IsLocalMethod(BfAstNode* nameNode);
|
||||
int QualifiedBacktrack(BfAstNode* endNode, int checkIdx, bool* outHadChevrons = NULL); // Backtracks to dot token
|
||||
BfTypeReference* DoCreateNamedTypeRef(BfIdentifierNode* identifierNode);
|
||||
BfTypeReference* DoCreateTypeRef(BfAstNode* identifierNode, bool parseArrayBracket = true);
|
||||
BfTypeReference* CreateTypeRef(BfAstNode* identifierNode, bool parseArrayBracket = true);
|
||||
BfTypeReference* CreateTypeRefAfter(BfAstNode* astNode, bool parseArrayBracket = true);
|
||||
BfTypeReference* CreateRefTypeRef(BfTypeReference* elementType, BfTokenNode* refToken);
|
||||
BfTypeReference* CreateConstTypeRef(BfTypeReference* elementType, BfTokenNode* refToken);
|
||||
bool ParseMethod(BfMethodDeclaration* methodDeclaration, SizedArrayImpl<BfParameterDeclaration*>* params, SizedArrayImpl<BfTokenNode*>* commas, bool alwaysIncludeBlock = false);
|
||||
BfGenericArgumentsNode* CreateGenericArguments(BfTokenNode* tokenNode);
|
||||
BfGenericParamsDeclaration* CreateGenericParamsDeclaration(BfTokenNode* tokenNode);
|
||||
BfGenericConstraintsDeclaration* CreateGenericConstraintsDeclaration(BfTokenNode* tokenNode);
|
||||
BfForEachStatement* CreateForEachStatement(BfAstNode* node, bool hasTypeDecl);
|
||||
BfStatement* CreateForStatement(BfAstNode* node);
|
||||
BfUsingStatement* CreateUsingStatement(BfAstNode* node);
|
||||
BfWhileStatement* CreateWhileStatement(BfAstNode* node);
|
||||
BfDoStatement* CreateDoStatement(BfAstNode* node);
|
||||
BfRepeatStatement* CreateRepeatStatement(BfAstNode* node);
|
||||
BfAstNode* CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDirective* attributes);
|
||||
BfAstNode* HandleTopLevel(BfBlock* node);
|
||||
BfInlineAsmStatement* CreateInlineAsmStatement(BfAstNode* asmNode);
|
||||
|
||||
void HandleBlock(BfBlock* block, bool allowEndingExpression = false);
|
||||
void HandleTypeDeclaration(BfTypeDeclaration* typeDecl, BfAttributeDirective* attributes);
|
||||
|
||||
public:
|
||||
BfReducer();
|
||||
void HandleRoot(BfRootNode* rootNode);
|
||||
};
|
||||
|
||||
NS_BF_END
|
143
IDEHelper/Compiler/BfResolvePass.cpp
Normal file
143
IDEHelper/Compiler/BfResolvePass.cpp
Normal file
|
@ -0,0 +1,143 @@
|
|||
#include "BfResolvePass.h"
|
||||
#include "BfParser.h"
|
||||
#include "BfModule.h"
|
||||
|
||||
USING_NS_BF;
|
||||
|
||||
BfResolvePassData::BfResolvePassData()
|
||||
{
|
||||
mGetSymbolReferenceKind = BfGetSymbolReferenceKind_None;
|
||||
|
||||
mSymbolReferenceTypeDef = NULL;
|
||||
|
||||
mSymbolReferenceLocalIdx = -1;
|
||||
mSymbolReferenceFieldIdx = -1;
|
||||
mSymbolReferenceMethodIdx = -1;
|
||||
mSymbolReferencePropertyIdx = -1;
|
||||
mSymbolMethodGenericParamIdx = -1;
|
||||
mSymbolTypeGenericParamIdx = -1;
|
||||
|
||||
mAutoComplete = NULL;
|
||||
mSourceClassifier = NULL;
|
||||
mResolveType = BfResolveType_None;
|
||||
mParser = NULL;
|
||||
}
|
||||
|
||||
void BfResolvePassData::RecordReplaceNode(BfParserData* parser, int srcStart, int srcLen)
|
||||
{
|
||||
String* stringPtr = NULL;
|
||||
if (!mFoundSymbolReferencesParserData.TryAdd(parser, NULL, &stringPtr))
|
||||
{
|
||||
*stringPtr += " ";
|
||||
}
|
||||
*stringPtr += StrFormat("%d %d", srcStart, srcLen);
|
||||
}
|
||||
|
||||
void BfResolvePassData::RecordReplaceNode(BfAstNode* node)
|
||||
{
|
||||
if (node->IsTemporary())
|
||||
return;
|
||||
auto parser = node->GetSourceData()->ToParserData();
|
||||
if (node->GetSrcStart() >= parser->mSrcLength)
|
||||
return;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (auto qualifiedName = BfNodeDynCast<BfQualifiedNameNode>(node))
|
||||
{
|
||||
node = qualifiedName->mRight;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
RecordReplaceNode(parser, node->GetSrcStart(), node->GetSrcLength());
|
||||
}
|
||||
|
||||
void BfResolvePassData::HandleMethodReference(BfAstNode* node, BfTypeDef* typeDef, BfMethodDef* methodDef)
|
||||
{
|
||||
if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Method) && (mSymbolReferenceTypeDef == typeDef) && (mSymbolReferenceMethodIdx == methodDef->mIdx))
|
||||
RecordReplaceNode(node);
|
||||
}
|
||||
|
||||
void BfResolvePassData::HandleFieldReference(BfAstNode* node, BfTypeDef* typeDef, BfFieldDef* fieldDef)
|
||||
{
|
||||
if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Field) && (mSymbolReferenceTypeDef == typeDef) && (mSymbolReferenceFieldIdx == fieldDef->mIdx))
|
||||
RecordReplaceNode(node);
|
||||
}
|
||||
|
||||
void BfResolvePassData::HandlePropertyReference(BfAstNode* node, BfTypeDef* typeDef, BfPropertyDef* propDef)
|
||||
{
|
||||
if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Property) && (mSymbolReferenceTypeDef == typeDef) && (mSymbolReferencePropertyIdx == propDef->mIdx))
|
||||
RecordReplaceNode(node);
|
||||
}
|
||||
|
||||
void BfResolvePassData::HandleLocalReference(BfIdentifierNode* identifier, BfTypeDef* typeDef, BfMethodDef* methodDef, int localVarIdx)
|
||||
{
|
||||
if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Local) && (mSymbolReferenceTypeDef == typeDef) && (mSymbolReferenceMethodIdx == methodDef->mIdx) && (localVarIdx == mSymbolReferenceLocalIdx))
|
||||
RecordReplaceNode(identifier);
|
||||
}
|
||||
|
||||
void BfResolvePassData::HandleTypeGenericParam(BfAstNode* node, BfTypeDef* typeDef, int genericParamIdx)
|
||||
{
|
||||
if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_TypeGenericParam) && (mSymbolReferenceTypeDef == typeDef) && (genericParamIdx == mSymbolTypeGenericParamIdx))
|
||||
RecordReplaceNode(node);
|
||||
}
|
||||
|
||||
void BfResolvePassData::HandleMethodGenericParam(BfAstNode* node, BfTypeDef* typeDef, BfMethodDef* methodDef, int genericParamIdx)
|
||||
{
|
||||
if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_MethodGenericParam) && (mSymbolReferenceTypeDef == typeDef) && (mSymbolReferenceMethodIdx == methodDef->mIdx) && (genericParamIdx == mSymbolMethodGenericParamIdx))
|
||||
RecordReplaceNode(node);
|
||||
}
|
||||
|
||||
void BfResolvePassData::HandleLocalReference(BfIdentifierNode* identifier, BfIdentifierNode* origNameNode, BfTypeDef* typeDef, BfMethodDef* methodDef, int localVarIdx)
|
||||
{
|
||||
if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Local) && (mSymbolReferenceTypeDef == typeDef) && (mSymbolReferenceMethodIdx == methodDef->mIdx) && (localVarIdx == mSymbolReferenceLocalIdx))
|
||||
{
|
||||
if (origNameNode == NULL)
|
||||
origNameNode = identifier;
|
||||
|
||||
int origLen = origNameNode->GetSrcLength();
|
||||
int refLen = identifier->GetSrcLength();
|
||||
|
||||
// The lengths can be different if we have one or more @'s prepended
|
||||
RecordReplaceNode(identifier->GetSourceData()->ToParserData(), identifier->GetSrcStart() + (refLen - origLen), origLen);
|
||||
}
|
||||
}
|
||||
|
||||
void BfResolvePassData::HandleTypeReference(BfAstNode* node, BfTypeDef* typeDef)
|
||||
{
|
||||
if ((mGetSymbolReferenceKind == BfGetSymbolReferenceKind_Type) && (mSymbolReferenceTypeDef == typeDef))
|
||||
{
|
||||
BfAstNode* baseNode = node;
|
||||
while (true)
|
||||
{
|
||||
if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(baseNode))
|
||||
{
|
||||
baseNode = qualifiedTypeRef->mRight;
|
||||
}
|
||||
else if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(baseNode))
|
||||
{
|
||||
baseNode = elementedTypeRef->mElementType;
|
||||
}
|
||||
else if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(baseNode))
|
||||
{
|
||||
baseNode = namedTypeRef->mNameNode;
|
||||
}
|
||||
else if (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(baseNode))
|
||||
{
|
||||
baseNode = qualifiedNameNode->mRight;
|
||||
}
|
||||
else if (auto declTypeRef = BfNodeDynCast<BfDeclTypeRef>(baseNode))
|
||||
{
|
||||
baseNode = NULL;
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (baseNode != NULL)
|
||||
RecordReplaceNode(baseNode);
|
||||
}
|
||||
}
|
85
IDEHelper/Compiler/BfResolvePass.h
Normal file
85
IDEHelper/Compiler/BfResolvePass.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
#pragma once
|
||||
|
||||
#include "BfSystem.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
enum BfResolveType
|
||||
{
|
||||
BfResolveType_None,
|
||||
BfResolveType_Classify,
|
||||
BfResolveType_ClassifyFullRefresh,
|
||||
BfResolveType_Autocomplete,
|
||||
BfResolveType_Autocomplete_HighPri,
|
||||
BfResolveType_GoToDefinition,
|
||||
BfResolveType_GetSymbolInfo,
|
||||
BfResolveType_RenameSymbol,
|
||||
BfResolveType_ShowFileSymbolReferences,
|
||||
BfResolveType_GetNavigationData,
|
||||
BfResolveType_GetCurrentLocation,
|
||||
BfResolveType_GetFixits,
|
||||
BfResolveType_GetTypeDefList,
|
||||
BfResolveType_GetTypeDefInto,
|
||||
BfResolveType_GetVarType,
|
||||
};
|
||||
|
||||
class BfLocalVariable;
|
||||
|
||||
enum BfGetSymbolReferenceKind
|
||||
{
|
||||
BfGetSymbolReferenceKind_None,
|
||||
BfGetSymbolReferenceKind_Local,
|
||||
BfGetSymbolReferenceKind_Method,
|
||||
BfGetSymbolReferenceKind_Field,
|
||||
BfGetSymbolReferenceKind_Property,
|
||||
BfGetSymbolReferenceKind_Type,
|
||||
BfGetSymbolReferenceKind_TypeGenericParam,
|
||||
BfGetSymbolReferenceKind_MethodGenericParam
|
||||
};
|
||||
|
||||
class BfResolvePassData
|
||||
{
|
||||
public:
|
||||
BfResolveType mResolveType;
|
||||
|
||||
BfParser* mParser;
|
||||
BfAutoComplete* mAutoComplete;
|
||||
Array<BfTypeDef*> mAutoCompleteTempTypes; // Contains multiple values when we have nested types
|
||||
BfSourceClassifier* mSourceClassifier;
|
||||
Array<BfAstNode*> mExteriorAutocompleteCheckNodes;
|
||||
|
||||
BfGetSymbolReferenceKind mGetSymbolReferenceKind;
|
||||
BfTypeDef* mSymbolReferenceTypeDef;
|
||||
|
||||
String mQueuedReplaceTypeDef;
|
||||
int mSymbolReferenceLocalIdx;
|
||||
int mSymbolReferenceFieldIdx;
|
||||
int mSymbolReferenceMethodIdx;
|
||||
int mSymbolReferencePropertyIdx;
|
||||
int mSymbolMethodGenericParamIdx;
|
||||
int mSymbolTypeGenericParamIdx;
|
||||
|
||||
typedef Dictionary<BfParserData*, String> FoundSymbolReferencesParserDataMap;
|
||||
FoundSymbolReferencesParserDataMap mFoundSymbolReferencesParserData;
|
||||
//std::vector<BfIdentifierNode*> mSymbolReferenceIdentifiers;
|
||||
|
||||
public:
|
||||
void RecordReplaceNode(BfParserData* parser, int srcStart, int srcLen);
|
||||
void RecordReplaceNode(BfAstNode* node);
|
||||
|
||||
public:
|
||||
BfResolvePassData();
|
||||
|
||||
void HandleLocalReference(BfIdentifierNode* identifier, BfTypeDef* typeDef, BfMethodDef* methodDef, int localVarIdx);
|
||||
void HandleLocalReference(BfIdentifierNode* identifier, BfIdentifierNode* origNameNode, BfTypeDef* typeDef, BfMethodDef* methodDef, int localVarIdx);
|
||||
void HandleTypeGenericParam(BfAstNode* node, BfTypeDef* typeDef, int genericParamIdx);
|
||||
void HandleMethodGenericParam(BfAstNode* node, BfTypeDef* typeDef, BfMethodDef* methodDef, int genericParamIdx);
|
||||
void HandleMethodReference(BfAstNode* node, BfTypeDef* typeDef, BfMethodDef* methodDef);
|
||||
void HandleFieldReference(BfAstNode* node, BfTypeDef* typeDef, BfFieldDef* fieldDef);
|
||||
void HandlePropertyReference(BfAstNode* node, BfTypeDef* typeDef, BfPropertyDef* propDef);
|
||||
void HandleTypeReference(BfAstNode* node, BfTypeDef* typeDef);
|
||||
|
||||
//void ReplaceIdentifiers();
|
||||
};
|
||||
|
||||
NS_BF_END
|
3820
IDEHelper/Compiler/BfResolvedTypeUtils.cpp
Normal file
3820
IDEHelper/Compiler/BfResolvedTypeUtils.cpp
Normal file
File diff suppressed because it is too large
Load diff
2305
IDEHelper/Compiler/BfResolvedTypeUtils.h
Normal file
2305
IDEHelper/Compiler/BfResolvedTypeUtils.h
Normal file
File diff suppressed because it is too large
Load diff
152
IDEHelper/Compiler/BfSource.cpp
Normal file
152
IDEHelper/Compiler/BfSource.cpp
Normal file
|
@ -0,0 +1,152 @@
|
|||
#include "BfSource.h"
|
||||
#include "BfSystem.h"
|
||||
#include "BfParser.h"
|
||||
|
||||
USING_NS_BF;
|
||||
|
||||
static int gSourceCount = 0;
|
||||
|
||||
BfSource::BfSource(BfSystem* bfSystem)
|
||||
{
|
||||
gSourceCount++;
|
||||
|
||||
mProject = NULL;
|
||||
mSystem = bfSystem;
|
||||
mAstAllocManager = NULL;
|
||||
if (bfSystem != NULL)
|
||||
mAstAllocManager = &gBfParserCache->mAstAllocManager;
|
||||
mSrc = NULL;
|
||||
|
||||
mSrcLength = 0;
|
||||
mSrcAllocSize = -1;
|
||||
|
||||
mErrorRootNode = NULL;
|
||||
mSidechannelRootNode = NULL;
|
||||
mRootNode = NULL;
|
||||
|
||||
mNextRevision = NULL;
|
||||
mPrevRevision = NULL;
|
||||
mSourceData = NULL;
|
||||
|
||||
mAstScratch = NULL;
|
||||
mIsClosed = false;
|
||||
mRefCount = 0;
|
||||
mParsingFailed = false;
|
||||
}
|
||||
|
||||
BfSource::~BfSource()
|
||||
{
|
||||
int sourceCount = gSourceCount--;
|
||||
|
||||
if (mSourceData != NULL)
|
||||
delete mSourceData;
|
||||
|
||||
if (mSrcAllocSize >= 0)
|
||||
delete mSrc;
|
||||
|
||||
for (auto typeDef : mTypeDefs)
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
}
|
||||
|
||||
bool BfSource::WantsStats()
|
||||
{
|
||||
auto parser = ToParser();
|
||||
if (parser == NULL)
|
||||
return false;
|
||||
return ((int)parser->mFileName.IndexOf("main2.cs") != -1);
|
||||
}
|
||||
|
||||
void BfSource::AddErrorNode(BfAstNode* astNode)
|
||||
{
|
||||
BfErrorNode* errorNode = BfNodeDynCast<BfErrorNode>(astNode);
|
||||
if (errorNode == NULL)
|
||||
{
|
||||
errorNode = mAlloc->Alloc<BfErrorNode>();
|
||||
errorNode->Init(astNode->GetSrcStart(), astNode->GetSrcStart(), astNode->GetSrcEnd());
|
||||
errorNode->mRefNode = astNode;
|
||||
}
|
||||
|
||||
mPendingErrorNodes.push_back(errorNode);
|
||||
}
|
||||
|
||||
int BfSource::AllocChars(int charCount)
|
||||
{
|
||||
if (mSrcLength + charCount > mSrcAllocSize)
|
||||
{
|
||||
int newAllocSize = std::max(mSrcLength + charCount, mSrcAllocSize * 2);
|
||||
char* newSrc = new char[newAllocSize + 1];
|
||||
memset(newSrc + mSrcAllocSize, 0, newAllocSize - mSrcAllocSize);
|
||||
if (mSrc != NULL)
|
||||
{
|
||||
memcpy(newSrc, mSrc, mSrcLength);
|
||||
delete mSrc;
|
||||
}
|
||||
mSrc = newSrc;
|
||||
mSrcAllocSize = newAllocSize;
|
||||
|
||||
BF_ASSERT(mSourceData->ToParser() != NULL);
|
||||
mSourceData->mSrc = mSrc;
|
||||
}
|
||||
|
||||
int retVal = mSrcLength;
|
||||
mSrcLength += charCount;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/*void BfSource::AddReplaceNode(BfAstNode* astNode, const StringImpl& replaceStr)
|
||||
{
|
||||
int srcStart = AllocChars((int)replaceStr.length());
|
||||
memcpy((char*)mSrc + srcStart, replaceStr.c_str(), (int)replaceStr.length());
|
||||
|
||||
auto replaceNode = mAlloc.Alloc<BfReplaceNode>();
|
||||
replaceNode->mSource = this;
|
||||
replaceNode->mSrcStart = srcStart;
|
||||
replaceNode->mSrcEnd = srcStart + (int)replaceStr.length();
|
||||
|
||||
astNode->Add(replaceNode);
|
||||
}
|
||||
*/
|
||||
|
||||
int NodeCompare(const void* lhs, const void* rhs)
|
||||
{
|
||||
//BfAstNode* leftNode = *((ASTREF(BfAstNode*)*)lhs);
|
||||
//BfAstNode* rightNode = *((ASTREF(BfAstNode*)*)rhs);
|
||||
|
||||
BfAstNode* leftNode = *((ASTREF(BfAstNode*)*)lhs);
|
||||
BfAstNode* rightNode = *((ASTREF(BfAstNode*)*)rhs);
|
||||
return leftNode->GetSrcStart() - rightNode->GetSrcStart();
|
||||
}
|
||||
|
||||
void BfSource::FinishSideNodes()
|
||||
{
|
||||
if (!mPendingSideNodes.IsEmpty())
|
||||
{
|
||||
mSidechannelRootNode->Init(mPendingSideNodes, mAlloc);
|
||||
qsort(mSidechannelRootNode->mChildArr.mVals, mSidechannelRootNode->mChildArr.mSize, sizeof(ASTREF(BfAstNode*)), NodeCompare);
|
||||
mPendingSideNodes.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void BfSource::Close()
|
||||
{
|
||||
// if (mAlloc->mSource == NULL)
|
||||
// {
|
||||
// BF_ASSERT(mErrorRootNode == NULL);
|
||||
// BF_ASSERT(mPendingErrorNodes.size() == 0);
|
||||
// return;
|
||||
// }
|
||||
mAstScratch = mAlloc->AllocBytes(SCRATCH_SIZE, sizeof(void*));
|
||||
|
||||
FinishSideNodes();
|
||||
|
||||
if (!mPendingErrorNodes.IsEmpty())
|
||||
{
|
||||
mErrorRootNode->Init(mPendingErrorNodes, mAlloc);
|
||||
qsort(mErrorRootNode->mChildArr.mVals, mErrorRootNode->mChildArr.mSize, sizeof(ASTREF(BfAstNode*)), NodeCompare);
|
||||
mPendingErrorNodes.clear();
|
||||
}
|
||||
|
||||
mIsClosed = true;
|
||||
}
|
111
IDEHelper/Compiler/BfSource.h
Normal file
111
IDEHelper/Compiler/BfSource.h
Normal file
|
@ -0,0 +1,111 @@
|
|||
#pragma once
|
||||
|
||||
#include "BeefySysLib/Common.h"
|
||||
#include "BfAst.h"
|
||||
#include "BeefySysLib/util/BumpAllocator.h"
|
||||
#include "BeefySysLib/util/Hash.h"
|
||||
|
||||
NS_BF_BEGIN;
|
||||
|
||||
class BfProject;
|
||||
class BfParser;
|
||||
class BfParserData;
|
||||
|
||||
class BfSourceData
|
||||
{
|
||||
public:
|
||||
enum ExternalNodesState : int8
|
||||
{
|
||||
ExternalNodesState_Unchecked,
|
||||
ExternalNodesState_Success,
|
||||
ExternalNodesState_Failed
|
||||
};
|
||||
|
||||
public:
|
||||
const char* mSrc;
|
||||
int mSrcLength;
|
||||
BfAstAllocManager* mAstAllocManager;
|
||||
BfAstAllocator mAlloc;
|
||||
|
||||
BfRootNode* mSidechannelRootNode; // Holds comments and preprocessor nodes
|
||||
BfRootNode* mRootNode;
|
||||
BfRootNode* mErrorRootNode;
|
||||
|
||||
BfSizedArray<BfAstNode*> mExteriorNodes;
|
||||
int mExteriorNodesCheckIdx; // 0 = unchecked, -1 = failed, >0 means success and equals the BfSystem.mTypesIdx
|
||||
|
||||
BfSourceData()
|
||||
{
|
||||
mSrc = NULL;
|
||||
mSrcLength = 0;
|
||||
mAstAllocManager = NULL;
|
||||
mSidechannelRootNode = NULL;
|
||||
mRootNode = NULL;
|
||||
mErrorRootNode = NULL;
|
||||
mExteriorNodesCheckIdx = 0;
|
||||
}
|
||||
|
||||
virtual ~BfSourceData()
|
||||
{
|
||||
BF_ASSERT(mExteriorNodes.mSize >= 0);
|
||||
BF_ASSERT(mExteriorNodes.mSize < 0x00FFFFFF);
|
||||
delete mSrc;
|
||||
}
|
||||
|
||||
virtual BfParserData* ToParserData()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
virtual BfParser* ToParser()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
class BfSource
|
||||
{
|
||||
public:
|
||||
static const int SCRATCH_SIZE = sizeof(BfGenericInstanceTypeRef) + sizeof(BfDirectStrTypeReference);
|
||||
|
||||
BfSourceData* mSourceData;
|
||||
|
||||
BfProject* mProject;
|
||||
BfSystem* mSystem;
|
||||
BfAstAllocManager* mAstAllocManager;
|
||||
BfAstAllocator* mAlloc;
|
||||
const char* mSrc;
|
||||
int mSrcLength;
|
||||
int mSrcAllocSize;
|
||||
bool mParsingFailed;
|
||||
bool mIsClosed;
|
||||
uint8* mAstScratch;
|
||||
int mRefCount; // Refs from BfTypeDefs
|
||||
Array<BfTypeDef*> mTypeDefs;
|
||||
|
||||
BfRootNode* mSidechannelRootNode; // Holds comments and preprocessor nodes
|
||||
BfRootNode* mRootNode;
|
||||
BfRootNode* mErrorRootNode;
|
||||
|
||||
BfParser* mNextRevision;
|
||||
BfParser* mPrevRevision;
|
||||
|
||||
SizedArray<BfAstNode*, 8> mPendingSideNodes;
|
||||
SizedArray<BfAstNode*, 8> mPendingErrorNodes;
|
||||
|
||||
public:
|
||||
bool WantsStats();
|
||||
|
||||
public:
|
||||
BfSource(BfSystem* bfSystem);
|
||||
virtual ~BfSource();
|
||||
|
||||
virtual BfParser* ToParser() { return NULL; }
|
||||
|
||||
void AddErrorNode(BfAstNode* astNode);
|
||||
int AllocChars(int charCount);
|
||||
void FinishSideNodes();
|
||||
virtual void Close(); // Writing done, return unused pages but retain used pages
|
||||
};
|
||||
|
||||
NS_BF_END;
|
714
IDEHelper/Compiler/BfSourceClassifier.cpp
Normal file
714
IDEHelper/Compiler/BfSourceClassifier.cpp
Normal file
|
@ -0,0 +1,714 @@
|
|||
#include "BfSourceClassifier.h"
|
||||
#include "BfParser.h"
|
||||
|
||||
USING_NS_BF;
|
||||
|
||||
BfSourceClassifier::BfSourceClassifier(BfParser* bfParser, CharData* charData)
|
||||
{
|
||||
mParser = bfParser;
|
||||
mCharData = charData;
|
||||
mSkipMethodInternals = false;
|
||||
mSkipTypeDeclarations = false;
|
||||
mSkipAttributes = false;
|
||||
mIsSideChannel = false;
|
||||
mPreserveFlags = false;
|
||||
mClassifierPassId = 0;
|
||||
mEnabled = true;
|
||||
mPrevNode = NULL;
|
||||
mCurMember = NULL;
|
||||
}
|
||||
|
||||
void BfSourceClassifier::ModifyFlags(BfAstNode* node, uint8 andFlags, uint8 orFlags)
|
||||
{
|
||||
if (node != NULL)
|
||||
{
|
||||
ModifyFlags(node->GetSrcStart(), node->GetSrcEnd(), andFlags, orFlags);
|
||||
}
|
||||
}
|
||||
|
||||
void BfSourceClassifier::ModifyFlags(int startPos, int endPos, uint8 andFlags, uint8 orFlags)
|
||||
{
|
||||
if (!mEnabled)
|
||||
return;
|
||||
|
||||
endPos = std::min(endPos, mParser->mOrigSrcLength);
|
||||
for (int i = startPos; i < endPos; i++)
|
||||
{
|
||||
mCharData[i].mDisplayPassId = mClassifierPassId;
|
||||
mCharData[i].mDisplayFlags = (mCharData[i].mDisplayFlags & andFlags) | orFlags;
|
||||
}
|
||||
}
|
||||
|
||||
void BfSourceClassifier::SetElementType(BfAstNode* node, BfSourceElementType elementType)
|
||||
{
|
||||
if (node != NULL)
|
||||
{
|
||||
SetElementType(node->GetSrcStart(), node->GetSrcEnd(), elementType);
|
||||
}
|
||||
}
|
||||
|
||||
void BfSourceClassifier::SetElementType(int startPos, int endPos, BfSourceElementType elementType)
|
||||
{
|
||||
if (!mEnabled)
|
||||
return;
|
||||
|
||||
endPos = BF_MIN(endPos, mParser->mOrigSrcLength);
|
||||
for (int i = startPos; i < endPos; i++)
|
||||
{
|
||||
mCharData[i].mDisplayPassId = mClassifierPassId;
|
||||
mCharData[i].mDisplayTypeId = (uint8)elementType;
|
||||
}
|
||||
}
|
||||
|
||||
void BfSourceClassifier::VisitMembers(BfBlock* node)
|
||||
{
|
||||
mPrevNode = NULL;
|
||||
for (auto& childNodeRef : *node)
|
||||
{
|
||||
BfAstNode* child = childNodeRef;
|
||||
child->Accept(this);
|
||||
mPrevNode = child;
|
||||
}
|
||||
}
|
||||
|
||||
bool BfSourceClassifier::IsInterestedInMember(BfAstNode* node, bool forceSkip)
|
||||
{
|
||||
if ((mSkipMethodInternals || forceSkip) && (mParser->mCursorIdx != -1) &&
|
||||
(!node->Contains(mParser->mCursorIdx, 1, 0)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void BfSourceClassifier::HandleLeafNode(BfAstNode* node)
|
||||
{
|
||||
if (!mEnabled)
|
||||
return;
|
||||
|
||||
int nodeStart = node->GetSrcStart();
|
||||
int srcStart = nodeStart;
|
||||
int triviaStart = node->GetTriviaStart();
|
||||
if (triviaStart != -1)
|
||||
{
|
||||
srcStart = triviaStart;
|
||||
|
||||
if ((mIsSideChannel) && (mPrevNode != NULL))
|
||||
srcStart = std::max(mPrevNode->GetSrcEnd(), srcStart);
|
||||
}
|
||||
|
||||
if (nodeStart != srcStart)
|
||||
SetElementType(srcStart, nodeStart, BfSourceElementType_Normal);
|
||||
//SetElementType(srcStart, node->GetSrcEnd(), BfSourceElementType_Normal);
|
||||
if (!mPreserveFlags)
|
||||
ModifyFlags(srcStart, node->GetSrcEnd(), ~BfSourceElementFlag_CompilerFlags_Mask, 0);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfAstNode* node)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfErrorNode* errorNode)
|
||||
{
|
||||
//Visit(errorNode->ToBase());
|
||||
VisitChildNoRef(errorNode->mRefNode);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfFieldDeclaration* fieldDecl)
|
||||
{
|
||||
if (!IsInterestedInMember(fieldDecl))
|
||||
return;
|
||||
|
||||
BfElementVisitor::Visit(fieldDecl);
|
||||
|
||||
VisitChild(fieldDecl->mConstSpecifier);
|
||||
VisitChild(fieldDecl->mReadOnlySpecifier);
|
||||
VisitChild(fieldDecl->mTypeRef);
|
||||
VisitChild(fieldDecl->mNameNode);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfFieldDtorDeclaration* fieldDtorDecl)
|
||||
{
|
||||
Visit(fieldDtorDecl->ToBase());
|
||||
|
||||
BfElementVisitor::Visit(fieldDtorDecl);
|
||||
|
||||
if (fieldDtorDecl->mTildeToken != NULL)
|
||||
SetElementType(fieldDtorDecl->mTildeToken, BfSourceElementType_Method);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfPreprocesorIgnoredSectionNode* preprocesorIgnoredSection)
|
||||
{
|
||||
HandleLeafNode(preprocesorIgnoredSection);
|
||||
|
||||
Visit(preprocesorIgnoredSection->ToBase());
|
||||
|
||||
SetElementType(preprocesorIgnoredSection, BfSourceElementType_Comment);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfPreprocessorNode* preprocessorNode)
|
||||
{
|
||||
HandleLeafNode(preprocessorNode);
|
||||
|
||||
if (!mPreserveFlags)
|
||||
ModifyFlags(preprocessorNode, ~BfSourceElementFlag_CompilerFlags_Mask, 0);
|
||||
SetElementType(preprocessorNode, BfSourceElementType_Normal);
|
||||
|
||||
Visit(preprocessorNode->ToBase());
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfCommentNode* commentNode)
|
||||
{
|
||||
HandleLeafNode(commentNode);
|
||||
|
||||
Visit(commentNode->ToBase());
|
||||
|
||||
SetElementType(commentNode, BfSourceElementType_Comment);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfAttributeDirective* attributeDirective)
|
||||
{
|
||||
if (mSkipAttributes)
|
||||
return;
|
||||
|
||||
// Skip?
|
||||
{
|
||||
if (auto typeDeclaration = BfNodeDynCast<BfTypeDeclaration>(mCurMember))
|
||||
{
|
||||
if (typeDeclaration->mAttributes == attributeDirective)
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto methodDecl = BfNodeDynCast<BfMethodDeclaration>(mCurMember))
|
||||
{
|
||||
if (methodDecl->mAttributes == attributeDirective)
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto propDecl = BfNodeDynCast<BfPropertyDeclaration>(mCurMember))
|
||||
{
|
||||
if (propDecl->mAttributes == attributeDirective)
|
||||
return;
|
||||
|
||||
for (auto methodDeclaration : propDecl->mMethods)
|
||||
{
|
||||
if (methodDeclaration->mAttributes == attributeDirective)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BfElementVisitor::Visit(attributeDirective);
|
||||
|
||||
VisitChild(attributeDirective->mAttrCloseToken);
|
||||
|
||||
VisitChild(attributeDirective->mAttrOpenToken); // Either [ or ,
|
||||
VisitChild(attributeDirective->mAttrCloseToken);
|
||||
|
||||
if (attributeDirective->mAttributeTargetSpecifier != NULL)
|
||||
{
|
||||
VisitChild(attributeDirective->mAttributeTargetSpecifier->mTargetToken);
|
||||
VisitChild(attributeDirective->mAttributeTargetSpecifier->mColonToken);
|
||||
}
|
||||
|
||||
VisitChild(attributeDirective->mAttributeTypeRef);
|
||||
VisitChild(attributeDirective->mCtorOpenParen);
|
||||
VisitChild(attributeDirective->mCtorCloseParen);
|
||||
for (auto& arg : attributeDirective->mArguments)
|
||||
VisitChild(arg);
|
||||
for (auto& comma : attributeDirective->mCommas)
|
||||
VisitChild(comma);
|
||||
|
||||
VisitChild(attributeDirective->mNextAttribute);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfIdentifierNode* identifier)
|
||||
{
|
||||
HandleLeafNode(identifier);
|
||||
|
||||
Visit(identifier->ToBase());
|
||||
|
||||
SetElementType(identifier, BfSourceElementType_Identifier);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfQualifiedNameNode* qualifiedName)
|
||||
{
|
||||
Visit((BfAstNode*)qualifiedName);
|
||||
|
||||
VisitChild(qualifiedName->mLeft);
|
||||
VisitChild(qualifiedName->mDot);
|
||||
VisitChild(qualifiedName->mRight);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfThisExpression* thisExpr)
|
||||
{
|
||||
HandleLeafNode(thisExpr);
|
||||
Visit((BfAstNode*)thisExpr);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfBaseExpression* baseExpr)
|
||||
{
|
||||
HandleLeafNode(baseExpr);
|
||||
Visit((BfAstNode*)baseExpr);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfMemberReferenceExpression* memberRefExpr)
|
||||
{
|
||||
Visit((BfAstNode*)memberRefExpr);
|
||||
VisitChild(memberRefExpr->mTarget);
|
||||
VisitChild(memberRefExpr->mDotToken);
|
||||
VisitChild(memberRefExpr->mMemberName);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfNamedTypeReference* typeRef)
|
||||
{
|
||||
HandleLeafNode(typeRef);
|
||||
|
||||
Visit(typeRef->ToBase());
|
||||
|
||||
//auto identifier = typeRef->mNameNode;
|
||||
if (typeRef != NULL)
|
||||
{
|
||||
BfIdentifierNode* checkName = typeRef->mNameNode;
|
||||
while (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(checkName))
|
||||
{
|
||||
SetElementType(qualifiedNameNode->mRight, BfSourceElementType_TypeRef);
|
||||
checkName = qualifiedNameNode->mLeft;
|
||||
}
|
||||
if (checkName != NULL)
|
||||
SetElementType(checkName, BfSourceElementType_TypeRef);
|
||||
}
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfQualifiedTypeReference* qualifiedType)
|
||||
{
|
||||
Visit((BfAstNode*)qualifiedType);
|
||||
|
||||
VisitChild(qualifiedType->mLeft);
|
||||
VisitChild(qualifiedType->mDot);
|
||||
VisitChild(qualifiedType->mRight);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfRefTypeRef* typeRef)
|
||||
{
|
||||
Visit((BfAstNode*)typeRef);
|
||||
|
||||
VisitChild(typeRef->mRefToken);
|
||||
SetElementType(typeRef->mRefToken, BfSourceElementType_TypeRef);
|
||||
VisitChild(typeRef->mElementType);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfArrayTypeRef* arrayType)
|
||||
{
|
||||
Visit((BfAstNode*)arrayType);
|
||||
|
||||
VisitChild(arrayType->mElementType);
|
||||
VisitChild(arrayType->mOpenBracket);
|
||||
for (auto& param : arrayType->mParams)
|
||||
VisitChild(param);
|
||||
VisitChild(arrayType->mCloseBracket);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfPointerTypeRef* pointerType)
|
||||
{
|
||||
Visit((BfAstNode*)pointerType);
|
||||
|
||||
VisitChild(pointerType->mElementType);
|
||||
VisitChild(pointerType->mStarNode);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfGenericInstanceTypeRef* genericInstTypeRef)
|
||||
{
|
||||
BfElementVisitor::Visit(genericInstTypeRef);
|
||||
|
||||
VisitChild(genericInstTypeRef->mElementType);
|
||||
VisitChild(genericInstTypeRef->mOpenChevron);
|
||||
for (int i = 0; i < (int) genericInstTypeRef->mGenericArguments.size(); i++)
|
||||
{
|
||||
if (genericInstTypeRef->mCommas.mVals != NULL)
|
||||
{
|
||||
if ((i > 0) && (i - 1 < (int)genericInstTypeRef->mCommas.size()))
|
||||
VisitChild(genericInstTypeRef->mCommas[i - 1]);
|
||||
}
|
||||
VisitChild(genericInstTypeRef->mGenericArguments[i]);
|
||||
}
|
||||
VisitChild(genericInstTypeRef->mCloseChevron);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfLocalMethodDeclaration* methodDecl)
|
||||
{
|
||||
if (IsInterestedInMember(methodDecl, true))
|
||||
BfElementVisitor::Visit(methodDecl);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfLiteralExpression* literalExpr)
|
||||
{
|
||||
HandleLeafNode(literalExpr);
|
||||
|
||||
Visit(literalExpr->ToBase());
|
||||
|
||||
SetElementType(literalExpr, BfSourceElementType_Literal);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfTokenNode* tokenNode)
|
||||
{
|
||||
HandleLeafNode(tokenNode);
|
||||
|
||||
Visit(tokenNode->ToBase());
|
||||
|
||||
if (BfTokenIsKeyword(tokenNode->GetToken()))
|
||||
SetElementType(tokenNode, BfSourceElementType_Keyword);
|
||||
else
|
||||
SetElementType(tokenNode, BfSourceElementType_Normal);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfInvocationExpression* invocationExpr)
|
||||
{
|
||||
BfElementVisitor::Visit(invocationExpr);
|
||||
|
||||
BfAstNode* target = invocationExpr->mTarget;
|
||||
if (target == NULL)
|
||||
return;
|
||||
|
||||
if (auto scopedTarget = BfNodeDynCast<BfScopedInvocationTarget>(target))
|
||||
{
|
||||
target = scopedTarget->mTarget;
|
||||
VisitChild(scopedTarget->mScopeName);
|
||||
}
|
||||
|
||||
BfAstNode* identifier = NULL;
|
||||
if (auto qualifiedName = BfNodeDynCast<BfQualifiedNameNode>(target))
|
||||
{
|
||||
VisitChild(qualifiedName->mLeft);
|
||||
VisitChild(qualifiedName->mDot);
|
||||
identifier = qualifiedName->mRight;
|
||||
}
|
||||
else if (identifier = BfNodeDynCast<BfIdentifierNode>(target))
|
||||
{
|
||||
// Leave as BfAttributedIdentifierNode if that's the case
|
||||
identifier = target;
|
||||
}
|
||||
else if (auto qualifiedName = BfNodeDynCast<BfQualifiedNameNode>(target))
|
||||
{
|
||||
VisitChild(qualifiedName->mLeft);
|
||||
VisitChild(qualifiedName->mDot);
|
||||
identifier = qualifiedName->mRight;
|
||||
}
|
||||
else if (auto memberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(target))
|
||||
{
|
||||
VisitChild(memberRefExpr->mTarget);
|
||||
VisitChild(memberRefExpr->mDotToken);
|
||||
identifier = memberRefExpr->mMemberName;
|
||||
}
|
||||
|
||||
if (identifier != NULL)
|
||||
{
|
||||
if (auto attrIdentifier = BfNodeDynCast<BfAttributedIdentifierNode>(identifier))
|
||||
{
|
||||
VisitChild(attrIdentifier->mAttributes);
|
||||
identifier = attrIdentifier->mIdentifier;
|
||||
}
|
||||
|
||||
if (identifier != NULL)
|
||||
SetElementType(identifier, BfSourceElementType_Method);
|
||||
}
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfIndexerExpression* indexerExpr)
|
||||
{
|
||||
BfElementVisitor::Visit(indexerExpr);
|
||||
|
||||
VisitChild(indexerExpr->mTarget);
|
||||
VisitChild(indexerExpr->mOpenBracket);
|
||||
for (int i = 0; i < (int) indexerExpr->mArguments.size(); i++)
|
||||
{
|
||||
if (i > 0)
|
||||
VisitChild(indexerExpr->mCommas[i - 1]);
|
||||
VisitChild(indexerExpr->mArguments[i]);
|
||||
}
|
||||
VisitChild(indexerExpr->mCloseBracket);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfConstructorDeclaration* ctorDeclaration)
|
||||
{
|
||||
if (!IsInterestedInMember(ctorDeclaration))
|
||||
return;
|
||||
|
||||
BfElementVisitor::Visit(ctorDeclaration);
|
||||
VisitChild(ctorDeclaration->mThisToken);
|
||||
|
||||
auto identifier = ctorDeclaration->mThisToken;
|
||||
if (identifier == NULL)
|
||||
return;
|
||||
SetElementType(identifier, BfSourceElementType_Method);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfDestructorDeclaration* dtorDeclaration)
|
||||
{
|
||||
BfElementVisitor::Visit(dtorDeclaration);
|
||||
|
||||
VisitChild(dtorDeclaration->mTildeToken);
|
||||
VisitChild(dtorDeclaration->mThisToken);
|
||||
|
||||
auto identifier = dtorDeclaration->mThisToken;
|
||||
if (identifier == NULL)
|
||||
return;
|
||||
SetElementType(identifier, BfSourceElementType_Method);
|
||||
|
||||
identifier = dtorDeclaration->mTildeToken;
|
||||
if (identifier == NULL)
|
||||
return;
|
||||
SetElementType(identifier, BfSourceElementType_Method);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfMethodDeclaration* methodDeclaration)
|
||||
{
|
||||
if (!IsInterestedInMember(methodDeclaration))
|
||||
return;
|
||||
|
||||
SetAndRestoreValue<BfAstNode*> prevMember(mCurMember, methodDeclaration);
|
||||
|
||||
BfElementVisitor::Visit(methodDeclaration);
|
||||
|
||||
BfIdentifierNode* identifier = methodDeclaration->mNameNode;
|
||||
if (identifier == NULL)
|
||||
return;
|
||||
SetElementType(identifier, BfSourceElementType_Method);
|
||||
|
||||
if (methodDeclaration->mGenericParams != NULL)
|
||||
{
|
||||
for (auto& genericParam : methodDeclaration->mGenericParams->mGenericParams)
|
||||
{
|
||||
BfIdentifierNode* typeRef = genericParam;
|
||||
SetElementType(typeRef, BfSourceElementType_TypeRef);
|
||||
}
|
||||
}
|
||||
|
||||
if (methodDeclaration->mGenericConstraintsDeclaration != NULL)
|
||||
{
|
||||
for (auto constraint : methodDeclaration->mGenericConstraintsDeclaration->mGenericConstraints)
|
||||
{
|
||||
BfIdentifierNode* typeRef = constraint->mGenericParamName;
|
||||
if (typeRef != NULL)
|
||||
SetElementType(typeRef, BfSourceElementType_TypeRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfPropertyMethodDeclaration* propertyMethodDeclaration)
|
||||
{
|
||||
if ((propertyMethodDeclaration->mBody != NULL) && (!IsInterestedInMember(propertyMethodDeclaration->mBody)))
|
||||
return;
|
||||
|
||||
BfElementVisitor::Visit(propertyMethodDeclaration);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfPropertyDeclaration* propertyDeclaration)
|
||||
{
|
||||
SetAndRestoreValue<BfAstNode*> prevMember(mCurMember, propertyDeclaration);
|
||||
|
||||
BfElementVisitor::Visit(propertyDeclaration);
|
||||
|
||||
for (auto methodDeclaration : propertyDeclaration->mMethods)
|
||||
{
|
||||
if ((methodDeclaration != NULL) && (methodDeclaration->mNameNode != NULL))
|
||||
SetElementType(methodDeclaration->mNameNode, BfSourceElementType_Method);
|
||||
}
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfTypeDeclaration* typeDeclaration)
|
||||
{
|
||||
if (typeDeclaration->mIgnoreDeclaration)
|
||||
return;
|
||||
|
||||
SetAndRestoreValue<BfAstNode*> prevMember(mCurMember, typeDeclaration);
|
||||
|
||||
if (mSkipTypeDeclarations)
|
||||
{
|
||||
if (auto defineBlock = BfNodeDynCast<BfBlock>(typeDeclaration->mDefineNode))
|
||||
{
|
||||
// Clear out any potential "fail after" errors on the closing brace-
|
||||
// Can happen when we don't close out a namespace, for example
|
||||
if (defineBlock->mCloseBrace != NULL)
|
||||
VisitChild(defineBlock->mCloseBrace);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Handle(typeDeclaration);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Handle(BfTypeDeclaration* typeDeclaration)
|
||||
{
|
||||
if (mParser->mCursorIdx != -1)
|
||||
{
|
||||
// This is to fix a case where we are typing out a type name, so an "actualTypeDef" will not be found during autocomplete
|
||||
// and therefore we will not process the attributes. Removing this will cause classify flashing while typing
|
||||
SetAndRestoreValue<bool> prevSkipAttributes(mSkipAttributes, true);
|
||||
BfElementVisitor::Visit(typeDeclaration);
|
||||
}
|
||||
else
|
||||
BfElementVisitor::Visit(typeDeclaration);
|
||||
|
||||
llvm::SmallVector<BfTypeReference*, 2> mBaseClasses;
|
||||
llvm::SmallVector<BfAstNode*, 2> mBaseClassCommas;
|
||||
|
||||
if (typeDeclaration->mGenericParams != NULL)
|
||||
{
|
||||
for (auto& genericParam : typeDeclaration->mGenericParams->mGenericParams)
|
||||
{
|
||||
BfIdentifierNode* typeRef = genericParam;
|
||||
SetElementType(typeRef, BfSourceElementType_TypeRef);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeDeclaration->mGenericConstraintsDeclaration != NULL)
|
||||
{
|
||||
for (auto constraint : typeDeclaration->mGenericConstraintsDeclaration->mGenericConstraints)
|
||||
{
|
||||
BfIdentifierNode* typeRef = constraint->mGenericParamName;
|
||||
if (typeRef != NULL)
|
||||
SetElementType(typeRef, BfSourceElementType_TypeRef);
|
||||
}
|
||||
}
|
||||
|
||||
auto typeRef = typeDeclaration->mNameNode;
|
||||
if (typeRef != NULL)
|
||||
SetElementType(typeRef, BfSourceElementType_TypeRef);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::MarkSkipped(int startPos, int endPos)
|
||||
{
|
||||
for (int i = startPos; i < endPos; i++)
|
||||
{
|
||||
mCharData[i].mDisplayPassId = BfSourceDisplayId_SkipResult;
|
||||
}
|
||||
}
|
||||
|
||||
void BfSourceClassifier::MarkSkipped(BfAstNode* node)
|
||||
{
|
||||
MarkSkipped(node->GetSrcStart(), node->GetSrcEnd());
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfTypeAliasDeclaration* typeDeclaration)
|
||||
{
|
||||
if (typeDeclaration->mIgnoreDeclaration)
|
||||
return;
|
||||
|
||||
BfElementVisitor::Visit(typeDeclaration);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfUsingDirective* usingDirective)
|
||||
{
|
||||
BfElementVisitor::Visit(usingDirective);
|
||||
|
||||
auto checkIdentifier = usingDirective->mNamespace;
|
||||
if (checkIdentifier != NULL)
|
||||
{
|
||||
while (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(checkIdentifier))
|
||||
{
|
||||
SetElementType(qualifiedNameNode->mRight, BfSourceElementType_Namespace);
|
||||
checkIdentifier = qualifiedNameNode->mLeft;
|
||||
}
|
||||
|
||||
if (checkIdentifier != NULL)
|
||||
SetElementType(checkIdentifier, BfSourceElementType_Namespace);
|
||||
}
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfUsingStaticDirective* usingDirective)
|
||||
{
|
||||
BfElementVisitor::Visit(usingDirective);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfNamespaceDeclaration* namespaceDeclaration)
|
||||
{
|
||||
BfElementVisitor::Visit(namespaceDeclaration);
|
||||
|
||||
auto checkIdentifier = namespaceDeclaration->mNameNode;
|
||||
if (checkIdentifier != NULL)
|
||||
{
|
||||
while (auto qualifiedNameNode = BfNodeDynCast<BfQualifiedNameNode>(checkIdentifier))
|
||||
{
|
||||
SetElementType(qualifiedNameNode->mRight, BfSourceElementType_Namespace);
|
||||
checkIdentifier = qualifiedNameNode->mLeft;
|
||||
}
|
||||
|
||||
if (checkIdentifier != NULL)
|
||||
SetElementType(checkIdentifier, BfSourceElementType_Namespace);
|
||||
}
|
||||
}
|
||||
|
||||
bool BfSourceClassifier::WantsSkipParentMethod(BfAstNode* node)
|
||||
{
|
||||
if (!mSkipMethodInternals)
|
||||
return false;
|
||||
|
||||
#ifdef BF_AST_HAS_PARENT_MEMBER
|
||||
if (node->mParent->IsA<BfMethodDeclaration>())
|
||||
{
|
||||
BF_ASSERT(node->mParent == mCurMember);
|
||||
}
|
||||
if (auto propDecl = BfNodeDynCast<BfPropertyDeclaration>(node->mParent))
|
||||
{
|
||||
BF_ASSERT(node->mParent == mCurMember);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (auto methodDecl = BfNodeDynCast<BfMethodDeclaration>(mCurMember))
|
||||
{
|
||||
if (methodDecl->mBody == node)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (auto propDecl = BfNodeDynCast<BfPropertyDeclaration>(mCurMember))
|
||||
{
|
||||
for (auto methodDeclaration : propDecl->mMethods)
|
||||
{
|
||||
if (node == methodDeclaration->mBody)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfGenericConstraintsDeclaration* genericConstraints)
|
||||
{
|
||||
/*if (WantsSkipParentMethod(genericConstraints))
|
||||
return;*/
|
||||
BfElementVisitor::Visit(genericConstraints);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfBlock* block)
|
||||
{
|
||||
if (WantsSkipParentMethod(block))
|
||||
return;
|
||||
if (block->mOpenBrace != NULL)
|
||||
Visit(block->mOpenBrace);
|
||||
if (block->mCloseBrace != NULL)
|
||||
Visit(block->mCloseBrace);
|
||||
VisitMembers(block);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfRootNode* rootNode)
|
||||
{
|
||||
// Clear off the flags at the end
|
||||
ModifyFlags(mParser->mRootNode->GetSrcEnd(), mParser->mOrigSrcLength, 0, 0);
|
||||
|
||||
VisitMembers(rootNode);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfInlineAsmStatement* asmStmt)
|
||||
{
|
||||
if (asmStmt->mOpenBrace != NULL)
|
||||
Visit(asmStmt->mOpenBrace);
|
||||
if (asmStmt->mCloseBrace != NULL)
|
||||
Visit(asmStmt->mCloseBrace);
|
||||
|
||||
//VisitMembers(asmStmt);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfInlineAsmInstruction* asmInst)
|
||||
{
|
||||
//VisitMembers(asmInst);
|
||||
}
|
127
IDEHelper/Compiler/BfSourceClassifier.h
Normal file
127
IDEHelper/Compiler/BfSourceClassifier.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
#pragma once
|
||||
|
||||
#include "BeefySysLib/Common.h"
|
||||
#include "BfAst.h"
|
||||
#include "BfSystem.h"
|
||||
#include "BfElementVisitor.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
enum BfSourceElementType
|
||||
{
|
||||
BfSourceElementType_Normal,
|
||||
BfSourceElementType_Keyword,
|
||||
BfSourceElementType_Literal,
|
||||
BfSourceElementType_Identifier,
|
||||
BfSourceElementType_Type,
|
||||
BfSourceElementType_Comment,
|
||||
BfSourceElementType_Method,
|
||||
BfSourceElementType_TypeRef,
|
||||
BfSourceElementType_Namespace
|
||||
};
|
||||
|
||||
enum BfSourceElementFlags
|
||||
{
|
||||
BfSourceElementFlag_Error = 1,
|
||||
BfSourceElementFlag_Warning = 2,
|
||||
BfSourceElementFlag_IsAfter = 4,
|
||||
BfSourceElementFlag_Skipped = 8,
|
||||
BfSourceElementFlag_CompilerFlags_Mask = 0x0F,
|
||||
BfSourceElementFlag_MASK = 0xFF
|
||||
};
|
||||
|
||||
enum BfSourceDisplayId : uint8
|
||||
{
|
||||
BfSourceDisplayId_Cleared,
|
||||
BfSourceDisplayId_AutoComplete,
|
||||
BfSourceDisplayId_SpellCheck,
|
||||
BfSourceDisplayId_FullClassify,
|
||||
BfSourceDisplayId_SkipResult
|
||||
};
|
||||
|
||||
class BfSourceClassifier : public BfElementVisitor
|
||||
{
|
||||
public:
|
||||
struct CharData
|
||||
{
|
||||
char mChar;
|
||||
uint8 mDisplayPassId;
|
||||
uint8 mDisplayTypeId;
|
||||
uint8 mDisplayFlags;
|
||||
#ifdef INCLUDE_CHARDATA_CHARID
|
||||
uint32 mCharId; // Unique ID for each character, for tracking moving text
|
||||
#endif
|
||||
};
|
||||
|
||||
public:
|
||||
BfParser* mParser;
|
||||
CharData* mCharData;
|
||||
bool mEnabled;
|
||||
bool mSkipMethodInternals;
|
||||
bool mSkipTypeDeclarations;
|
||||
bool mSkipAttributes;
|
||||
bool mIsSideChannel;
|
||||
bool mPreserveFlags;
|
||||
uint8 mClassifierPassId;
|
||||
BfAstNode* mPrevNode;
|
||||
BfAstNode* mCurMember;
|
||||
|
||||
public:
|
||||
void HandleLeafNode(BfAstNode* node);
|
||||
void VisitMembers(BfBlock* node);
|
||||
void ModifyFlags(BfAstNode* node, uint8 andFlags, uint8 orFlags);
|
||||
void ModifyFlags(int startPos, int endPos, uint8 andFlags, uint8 orFlags);
|
||||
void SetElementType(BfAstNode* node, BfSourceElementType elementType);
|
||||
void SetElementType(int startPos, int endPos, BfSourceElementType elementType);
|
||||
bool IsInterestedInMember(BfAstNode* node, bool forceSkip = false);
|
||||
bool WantsSkipParentMethod(BfAstNode* node);
|
||||
void Handle(BfTypeDeclaration* typeDeclaration);
|
||||
void MarkSkipped(int startPos, int endPos);
|
||||
void MarkSkipped(BfAstNode* node);
|
||||
|
||||
public:
|
||||
BfSourceClassifier(BfParser* bfParser, CharData* charData);
|
||||
|
||||
virtual void Visit(BfGenericConstraintsDeclaration* genericConstraints) override;
|
||||
|
||||
virtual void Visit(BfAstNode* node) override;
|
||||
virtual void Visit(BfErrorNode* errorNode) override;
|
||||
virtual void Visit(BfFieldDeclaration* fieldDecl) override;
|
||||
virtual void Visit(BfFieldDtorDeclaration* fieldDtorDecl) override;
|
||||
virtual void Visit(BfPreprocesorIgnoredSectionNode* preprocesorIgnoredSection) override;
|
||||
virtual void Visit(BfPreprocessorNode* preprocessorNode) override;
|
||||
virtual void Visit(BfCommentNode* commentNode) override;
|
||||
virtual void Visit(BfAttributeDirective* attributeDirective) override;
|
||||
virtual void Visit(BfIdentifierNode* identifier) override;
|
||||
virtual void Visit(BfQualifiedNameNode* identifier) override;
|
||||
virtual void Visit(BfThisExpression* thisExpr) override;
|
||||
virtual void Visit(BfBaseExpression* baseExpr) override;
|
||||
virtual void Visit(BfMemberReferenceExpression* memberRefExpr) override;
|
||||
virtual void Visit(BfQualifiedTypeReference* qualifiedType) override;
|
||||
virtual void Visit(BfRefTypeRef* typeRef) override;
|
||||
virtual void Visit(BfArrayTypeRef* arrayType) override;
|
||||
virtual void Visit(BfPointerTypeRef* pointerType) override;
|
||||
virtual void Visit(BfNamedTypeReference* typeRef) override;
|
||||
virtual void Visit(BfGenericInstanceTypeRef* typeRef) override;
|
||||
virtual void Visit(BfLocalMethodDeclaration * methodDecl) override;
|
||||
virtual void Visit(BfLiteralExpression* literalExpr) override;
|
||||
virtual void Visit(BfTokenNode* tokenNode) override;
|
||||
virtual void Visit(BfInvocationExpression* invocationExpr) override;
|
||||
virtual void Visit(BfIndexerExpression* indexerExpr) override;
|
||||
virtual void Visit(BfConstructorDeclaration* ctorDeclaration) override;
|
||||
virtual void Visit(BfDestructorDeclaration* dtorDeclaration) override;
|
||||
virtual void Visit(BfMethodDeclaration* methodDeclaration) override;
|
||||
virtual void Visit(BfPropertyMethodDeclaration* propertyMethodDeclaration) override;
|
||||
virtual void Visit(BfPropertyDeclaration* propertyDeclaration) override;
|
||||
virtual void Visit(BfTypeDeclaration* typeDeclaration) override;
|
||||
virtual void Visit(BfTypeAliasDeclaration* typeDeclaration) override;
|
||||
virtual void Visit(BfUsingDirective* usingDirective) override;
|
||||
virtual void Visit(BfUsingStaticDirective* usingDirective) override;
|
||||
virtual void Visit(BfNamespaceDeclaration* namespaceDeclaration) override;
|
||||
virtual void Visit(BfBlock* block) override;
|
||||
virtual void Visit(BfRootNode* rootNode) override;
|
||||
virtual void Visit(BfInlineAsmStatement* asmStmt) override;
|
||||
virtual void Visit(BfInlineAsmInstruction* asmInst) override;
|
||||
};
|
||||
|
||||
NS_BF_END
|
17
IDEHelper/Compiler/BfSourcePositionFinder.cpp
Normal file
17
IDEHelper/Compiler/BfSourcePositionFinder.cpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include "BfSourcePositionFinder.h"
|
||||
#include "BfParser.h"
|
||||
|
||||
USING_NS_BF;
|
||||
|
||||
BfSourcePositionFinder::BfSourcePositionFinder(BfParser* bfParser, int findPosition)
|
||||
{
|
||||
mParser = bfParser;
|
||||
mFindPosition = findPosition;
|
||||
mClosestElement = NULL;
|
||||
}
|
||||
|
||||
void BfSourcePositionFinder::Visit(BfAstNode* node)
|
||||
{
|
||||
if ((mFindPosition >= node->GetSrcStart()) && (mFindPosition <= node->GetSrcEnd()))
|
||||
mClosestElement = node;
|
||||
}
|
22
IDEHelper/Compiler/BfSourcePositionFinder.h
Normal file
22
IDEHelper/Compiler/BfSourcePositionFinder.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#include "BeefySysLib/Common.h"
|
||||
#include "BfAst.h"
|
||||
#include "BfSystem.h"
|
||||
#include "BfElementVisitor.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
class BfSourcePositionFinder : public BfElementVisitor
|
||||
{
|
||||
public:
|
||||
BfParser* mParser;
|
||||
int mFindPosition;
|
||||
BfAstNode* mClosestElement;
|
||||
|
||||
public:
|
||||
BfSourcePositionFinder(BfParser* bfParser, int findPosition);
|
||||
|
||||
using BfStructuralVisitor::Visit;
|
||||
virtual void Visit(BfAstNode* node) override;
|
||||
};
|
||||
|
||||
NS_BF_END
|
6862
IDEHelper/Compiler/BfStmtEvaluator.cpp
Normal file
6862
IDEHelper/Compiler/BfStmtEvaluator.cpp
Normal file
File diff suppressed because it is too large
Load diff
3789
IDEHelper/Compiler/BfSystem.cpp
Normal file
3789
IDEHelper/Compiler/BfSystem.cpp
Normal file
File diff suppressed because it is too large
Load diff
1476
IDEHelper/Compiler/BfSystem.h
Normal file
1476
IDEHelper/Compiler/BfSystem.h
Normal file
File diff suppressed because it is too large
Load diff
7
IDEHelper/Compiler/BfType.h
Normal file
7
IDEHelper/Compiler/BfType.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#include "BeefySysLib/Common.h"
|
||||
#include "BfAst.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
|
||||
NS_BF_END
|
62
IDEHelper/Compiler/BfUtil.cpp
Normal file
62
IDEHelper/Compiler/BfUtil.cpp
Normal file
|
@ -0,0 +1,62 @@
|
|||
#include "BfUtil.h"
|
||||
|
||||
USING_NS_BF;
|
||||
|
||||
void* Beefy::DecodeLocalDataPtr(const char*& strRef)
|
||||
{
|
||||
void* val = (void*)stouln(strRef, sizeof(intptr) * 2);
|
||||
strRef += sizeof(intptr) * 2;
|
||||
return val;
|
||||
}
|
||||
|
||||
String Beefy::EncodeDataPtr(void* addr, bool doPrefix)
|
||||
{
|
||||
if (doPrefix)
|
||||
{
|
||||
return StrFormat("0x%p", addr);
|
||||
}
|
||||
else
|
||||
return StrFormat("%p", addr);
|
||||
}
|
||||
|
||||
String Beefy::EncodeDataPtr(uint32 addr, bool doPrefix)
|
||||
{
|
||||
if (doPrefix)
|
||||
return StrFormat("0x%08X", addr);
|
||||
else
|
||||
return StrFormat("%08X", addr);
|
||||
}
|
||||
|
||||
String Beefy::EncodeDataPtr(uint64 addr, bool doPrefix)
|
||||
{
|
||||
if (doPrefix)
|
||||
return StrFormat("0x%@", addr);
|
||||
else
|
||||
return StrFormat("%p", addr);
|
||||
}
|
||||
|
||||
void* Beefy::ZeroedAlloc(int size)
|
||||
{
|
||||
//uint8* data = new uint8[size];
|
||||
uint8* data = (uint8*)malloc(size);
|
||||
BF_ASSERT(((intptr)data & 7) == 0);
|
||||
memset(data, 0, size);
|
||||
return data;
|
||||
}
|
||||
|
||||
uint64 stouln(const char* str, int len)
|
||||
{
|
||||
uint64 val = 0;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
char c = str[i];
|
||||
val *= 0x10;
|
||||
if ((c >= '0') && (c <= '9'))
|
||||
val += c - '0';
|
||||
else if ((c >= 'A') && (c <= 'F'))
|
||||
val += (c - 'A') + 0xA;
|
||||
else if ((c >= 'a') && (c <= 'f'))
|
||||
val += (c - 'a') + 0xa;
|
||||
}
|
||||
return val;
|
||||
}
|
340
IDEHelper/Compiler/BfUtil.h
Normal file
340
IDEHelper/Compiler/BfUtil.h
Normal file
|
@ -0,0 +1,340 @@
|
|||
#pragma once
|
||||
|
||||
#include "BeefySysLib/Common.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
template <typename T>
|
||||
class AutoPopBack
|
||||
{
|
||||
public:
|
||||
T* mList;
|
||||
|
||||
public:
|
||||
AutoPopBack(T* list)
|
||||
{
|
||||
mList = list;
|
||||
}
|
||||
|
||||
~AutoPopBack()
|
||||
{
|
||||
if (mList != NULL)
|
||||
mList->pop_back();
|
||||
}
|
||||
|
||||
void Pop()
|
||||
{
|
||||
if (mList != NULL)
|
||||
mList->pop_back();
|
||||
mList = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class SetAndRestoreValue
|
||||
{
|
||||
public:
|
||||
T* mVarPtr;
|
||||
T mPrevVal;
|
||||
T mNewVal;
|
||||
|
||||
public:
|
||||
SetAndRestoreValue()
|
||||
{
|
||||
mVarPtr = NULL;
|
||||
}
|
||||
|
||||
SetAndRestoreValue(T& varRef)
|
||||
{
|
||||
mPrevVal = varRef;
|
||||
mVarPtr = &varRef;
|
||||
mNewVal = mPrevVal;
|
||||
}
|
||||
|
||||
SetAndRestoreValue(T& varRef, T newVal)
|
||||
{
|
||||
mPrevVal = varRef;
|
||||
mVarPtr = &varRef;
|
||||
varRef = newVal;
|
||||
mNewVal = newVal;
|
||||
}
|
||||
|
||||
SetAndRestoreValue(T& varRef, T newVal, bool doSet)
|
||||
{
|
||||
mPrevVal = varRef;
|
||||
mVarPtr = &varRef;
|
||||
if (doSet)
|
||||
varRef = newVal;
|
||||
mNewVal = newVal;
|
||||
}
|
||||
|
||||
void Init(T& varRef, T newVal)
|
||||
{
|
||||
mPrevVal = varRef;
|
||||
mVarPtr = &varRef;
|
||||
varRef = newVal;
|
||||
mNewVal = newVal;
|
||||
}
|
||||
|
||||
~SetAndRestoreValue()
|
||||
{
|
||||
Restore();
|
||||
}
|
||||
|
||||
void Restore()
|
||||
{
|
||||
if (mVarPtr != NULL)
|
||||
*mVarPtr = mPrevVal;
|
||||
}
|
||||
|
||||
void CancelRestore()
|
||||
{
|
||||
mVarPtr = NULL;
|
||||
}
|
||||
|
||||
void Set()
|
||||
{
|
||||
*mVarPtr = mNewVal;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class OwnedVector : public Array<T*>
|
||||
{
|
||||
public:
|
||||
typedef Array<T*> _Base;
|
||||
|
||||
~OwnedVector()
|
||||
{
|
||||
for (auto item : *this)
|
||||
delete item;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
for (auto item : *this)
|
||||
delete item;
|
||||
_Base::Clear();
|
||||
}
|
||||
|
||||
void ClearWithoutDeleting()
|
||||
{
|
||||
_Base::Clear();
|
||||
}
|
||||
|
||||
T* Alloc()
|
||||
{
|
||||
T* item = new T();
|
||||
_Base::push_back(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
template <typename T2>
|
||||
T2* Alloc()
|
||||
{
|
||||
T2* item = new T2();
|
||||
_Base::push_back(item);
|
||||
return item;
|
||||
}
|
||||
};
|
||||
|
||||
// Optimized for Get and then immediate GiveBack - no allocation or vector access
|
||||
template <typename T>
|
||||
class BfAllocPool
|
||||
{
|
||||
public:
|
||||
Array<T*> mVals;
|
||||
T* mNext;
|
||||
bool mOwnsAll;
|
||||
|
||||
public:
|
||||
BfAllocPool(bool ownsAll = false)
|
||||
{
|
||||
mOwnsAll = ownsAll;
|
||||
mNext = NULL;
|
||||
}
|
||||
|
||||
~BfAllocPool()
|
||||
{
|
||||
if ((mNext != NULL) && (!mOwnsAll))
|
||||
delete mNext;
|
||||
for (auto val : mVals)
|
||||
{
|
||||
val->~T();
|
||||
free(val);
|
||||
}
|
||||
}
|
||||
|
||||
T* Get()
|
||||
{
|
||||
T* val = mNext;
|
||||
if (val == NULL)
|
||||
{
|
||||
if ((mVals.size() > 0) && (!mOwnsAll))
|
||||
{
|
||||
val = mVals.back();
|
||||
mVals.pop_back();
|
||||
return val;
|
||||
}
|
||||
//val = new T();
|
||||
void* addr = malloc(sizeof(T));
|
||||
memset(addr, 0, sizeof(T));
|
||||
val = new(addr) T();
|
||||
if (mOwnsAll)
|
||||
mVals.push_back(val);
|
||||
return val;
|
||||
}
|
||||
mNext = NULL;
|
||||
return val;
|
||||
}
|
||||
|
||||
void GiveBack(T* val)
|
||||
{
|
||||
if (mNext == NULL)
|
||||
mNext = val;
|
||||
else if (!mOwnsAll)
|
||||
mVals.push_back(val);
|
||||
}
|
||||
};
|
||||
|
||||
inline uint64_t DecodeULEB128(const uint8*& p)
|
||||
{
|
||||
uint64_t val = 0;
|
||||
unsigned shift = 0;
|
||||
do
|
||||
{
|
||||
val += uint64_t(*p & 0x7f) << shift;
|
||||
shift += 7;
|
||||
} while ((*p++ & 0x80) != 0);
|
||||
return val;
|
||||
}
|
||||
|
||||
inline void EncodeSLEB128(uint8*& buf, int value)
|
||||
{
|
||||
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;
|
||||
*(buf++) = curByte;
|
||||
}
|
||||
while (hasMore);
|
||||
}
|
||||
|
||||
inline void EncodeSLEB128(uint8*& buf, int64_t value)
|
||||
{
|
||||
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;
|
||||
*(buf++) = curByte;
|
||||
}
|
||||
while (hasMore);
|
||||
}
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4146)
|
||||
|
||||
/// Utility function to decode a SLEB128 value.
|
||||
inline int64_t DecodeSLEB128(const uint8*& p)
|
||||
{
|
||||
int value = 0;
|
||||
int shift = 0;
|
||||
int curByte;
|
||||
do
|
||||
{
|
||||
curByte = (uint8_t)*p++;
|
||||
value |= ((curByte & 0x7f) << shift);
|
||||
shift += 7;
|
||||
|
||||
} while (curByte >= 128);
|
||||
// Sign extend negative numbers.
|
||||
if (((curByte & 0x40) != 0) && (shift < 64))
|
||||
value |= ~0LL << shift; //-V610
|
||||
return value;
|
||||
}
|
||||
|
||||
#pragma warning(pop)
|
||||
|
||||
void* DecodeLocalDataPtr(const char*& strRef);
|
||||
String EncodeDataPtr(void* addr, bool doPrefix);
|
||||
String EncodeDataPtr(uint32 addr, bool doPrefix);
|
||||
String EncodeDataPtr(uint64 addr, bool doPrefix);
|
||||
void* ZeroedAlloc(int size);
|
||||
/*template <typename T>
|
||||
T* ZeroedAlloc()
|
||||
{
|
||||
return new (ZeroedAlloc(sizeof(T))) T();
|
||||
}*/
|
||||
|
||||
template <typename T>
|
||||
T* PlaceNew(void* addr)
|
||||
{
|
||||
return new(addr) T();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* ZeroPlaceNew(void* addr)
|
||||
{
|
||||
memset(addr, 0, sizeof(T));
|
||||
return new(addr) T();
|
||||
}
|
||||
|
||||
class CaseInsensitiveString
|
||||
{
|
||||
public:
|
||||
const char* mStr;
|
||||
|
||||
CaseInsensitiveString(const char* str)
|
||||
{
|
||||
mStr = str;
|
||||
}
|
||||
|
||||
bool operator==(const CaseInsensitiveString& strB) const
|
||||
{
|
||||
return _stricmp(mStr, strB.mStr) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
#define TOKENPASTE(X, Y) X ## Y
|
||||
#define TOKENPASTE2(X, Y) TOKENPASTE(X, Y)
|
||||
|
||||
#define STACK_ZERO_INIT(T, NAME) \
|
||||
alignas(16) uint8 TOKENPASTE2(_data__, __LINE__)[sizeof(T)]; \
|
||||
memset(TOKENPASTE2(_data__, __LINE__), 0, sizeof(T)); \
|
||||
T* NAME = PlaceNew<T>(TOKENPASTE2(_data__, __LINE__));
|
||||
|
||||
NS_BF_END
|
||||
|
||||
uint64 stouln(const char* str, int len);
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<>
|
||||
struct hash<Beefy::CaseInsensitiveString>
|
||||
{
|
||||
size_t operator()(const Beefy::CaseInsensitiveString& val) const
|
||||
{
|
||||
int curHash = 0;
|
||||
const char* str = val.mStr;
|
||||
while (true)
|
||||
{
|
||||
char c = *(str++);
|
||||
if (c == 0)
|
||||
break;
|
||||
c = tolower(c);
|
||||
curHash = ((curHash ^ c) << 5) - curHash;
|
||||
}
|
||||
return curHash;
|
||||
}
|
||||
};
|
||||
}
|
13
IDEHelper/Compiler/BfVarDeclChecker.cpp
Normal file
13
IDEHelper/Compiler/BfVarDeclChecker.cpp
Normal file
|
@ -0,0 +1,13 @@
|
|||
#include "BfVarDeclChecker.h"
|
||||
|
||||
USING_NS_BF;
|
||||
|
||||
BfVarDeclChecker::BfVarDeclChecker()
|
||||
{
|
||||
mHasVarDecl = false;
|
||||
}
|
||||
|
||||
void BfVarDeclChecker::Visit(BfVariableDeclaration * binOpExpr)
|
||||
{
|
||||
mHasVarDecl = true;
|
||||
}
|
21
IDEHelper/Compiler/BfVarDeclChecker.h
Normal file
21
IDEHelper/Compiler/BfVarDeclChecker.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include "BeefySysLib/Common.h"
|
||||
#include "BfAst.h"
|
||||
#include "BfElementVisitor.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
class BfVarDeclChecker : public BfElementVisitor
|
||||
{
|
||||
public:
|
||||
bool mHasVarDecl;
|
||||
|
||||
public:
|
||||
BfVarDeclChecker();
|
||||
|
||||
virtual void Visit(BfVariableDeclaration* binOpExpr) override;
|
||||
};
|
||||
|
||||
|
||||
NS_BF_END
|
100
IDEHelper/Compiler/MemReporter.cpp
Normal file
100
IDEHelper/Compiler/MemReporter.cpp
Normal file
|
@ -0,0 +1,100 @@
|
|||
#include "MemReporter.h"
|
||||
|
||||
USING_NS_BF;
|
||||
|
||||
MemReporter::MemReporter()
|
||||
{
|
||||
mCurEntry = &mRoot;
|
||||
mRoot.mName = "Root";
|
||||
mShowInKB = true;
|
||||
}
|
||||
|
||||
MemReporter::~MemReporter()
|
||||
{
|
||||
}
|
||||
|
||||
int MemReporter::GetChildSizes(Entry* entry)
|
||||
{
|
||||
int childSizes = 0;
|
||||
for (auto& childPair : entry->mChildren)
|
||||
{
|
||||
auto child = childPair.mValue;
|
||||
childSizes += child->mSize + GetChildSizes(child);
|
||||
}
|
||||
return childSizes;
|
||||
}
|
||||
|
||||
void MemReporter::Report(int depth, Entry* entry)
|
||||
{
|
||||
String str;
|
||||
for (int i = 0; i < depth; i++)
|
||||
str += " ";
|
||||
|
||||
str += entry->mName;
|
||||
while (str.length() < 64)
|
||||
str += ' ';
|
||||
|
||||
if (entry->mChildSize == -1)
|
||||
entry->mChildSize = GetChildSizes(entry);
|
||||
|
||||
if (mShowInKB)
|
||||
str += StrFormat("%6d %6dk %6dk\r\n", entry->mCount, entry->mSize / 1024, (entry->mSize + entry->mChildSize) / 1024);
|
||||
else
|
||||
str += StrFormat("%6d %6d %6d\r\n", entry->mCount, entry->mSize, (entry->mSize + entry->mChildSize));
|
||||
BfpOutput_DebugString(str.c_str());
|
||||
|
||||
Array<Entry*> entries;
|
||||
for (auto& kv : entry->mChildren)
|
||||
{
|
||||
auto* entry = kv.mValue;
|
||||
entry->mChildSize = GetChildSizes(entry);
|
||||
entries.Add(kv.mValue);
|
||||
}
|
||||
|
||||
entries.Sort([](Entry* lhs, Entry* rhs) { return (lhs->mSize + lhs->mChildSize) > (rhs->mSize + rhs->mChildSize); });
|
||||
|
||||
for (auto& entry : entries)
|
||||
{
|
||||
Report(depth + 1, entry);
|
||||
}
|
||||
}
|
||||
|
||||
void MemReporter::BeginSection(const StringImpl& name)
|
||||
{
|
||||
Entry** entryPtr;
|
||||
if (!mCurEntry->mChildren.TryAdd(name, NULL, &entryPtr))
|
||||
{
|
||||
mCurEntry = *entryPtr;
|
||||
mCurEntry->mCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
auto newEntry = mAlloc.Alloc<Entry>();
|
||||
newEntry->mCount++;
|
||||
newEntry->mName = name;
|
||||
newEntry->mParent = mCurEntry;
|
||||
*entryPtr = newEntry;
|
||||
mCurEntry = newEntry;
|
||||
}
|
||||
|
||||
void MemReporter::Add(int size)
|
||||
{
|
||||
mCurEntry->mSize += size;
|
||||
}
|
||||
|
||||
void MemReporter::Add(const StringImpl& name, int size)
|
||||
{
|
||||
BeginSection(name);
|
||||
Add(size);
|
||||
EndSection();
|
||||
}
|
||||
|
||||
void MemReporter::EndSection()
|
||||
{
|
||||
mCurEntry = mCurEntry->mParent;
|
||||
}
|
||||
|
||||
void MemReporter::Report()
|
||||
{
|
||||
Report(0, &mRoot);
|
||||
}
|
191
IDEHelper/Compiler/MemReporter.h
Normal file
191
IDEHelper/Compiler/MemReporter.h
Normal file
|
@ -0,0 +1,191 @@
|
|||
#pragma once
|
||||
|
||||
#include "BeefySysLib/Common.h"
|
||||
#include "BeefySysLib/util/CritSect.h"
|
||||
#include "BeefySysLib/util/Hash.h"
|
||||
#include "BeefySysLib/util/String.h"
|
||||
#include "BeefySysLib/util/BumpAllocator.h"
|
||||
#include "BeefySysLib/util/Dictionary.h"
|
||||
#include <vector>
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
class MemReporter
|
||||
{
|
||||
public:
|
||||
struct Entry
|
||||
{
|
||||
Dictionary<String, Entry*> mChildren;
|
||||
String mName;
|
||||
int mSize;
|
||||
int mChildSize;
|
||||
int mCount;
|
||||
Entry* mParent;
|
||||
|
||||
Entry()
|
||||
{
|
||||
mSize = 0;
|
||||
mChildSize = -1;
|
||||
mParent = NULL;
|
||||
mCount = 0;
|
||||
}
|
||||
};
|
||||
|
||||
BumpAllocator mAlloc;
|
||||
Entry mRoot;
|
||||
Entry* mCurEntry;
|
||||
bool mShowInKB;
|
||||
|
||||
public:
|
||||
int GetChildSizes(Entry* entry);
|
||||
void Report(int depth, Entry* entry);
|
||||
|
||||
public:
|
||||
MemReporter();
|
||||
~MemReporter();
|
||||
|
||||
void BeginSection(const StringImpl& name);
|
||||
void Add(int size);
|
||||
void Add(const StringImpl& name, int size);
|
||||
|
||||
template <typename T>
|
||||
void AddVec(const T& vec, bool addContainerSize = true)
|
||||
{
|
||||
Add((addContainerSize ? sizeof(T) : 0) + (int)vec.mAllocSize * sizeof(typename T::value_type));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AddVec(const StringImpl& name, const T& vec, bool addContainerSize = true)
|
||||
{
|
||||
BeginSection(name);
|
||||
Add((addContainerSize ? sizeof(T) : 0) + (int)vec.mAllocSize * sizeof(typename T::value_type));
|
||||
EndSection();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AddVecPtr(const std::vector<T>& vec, bool addContainerSize = true)
|
||||
{
|
||||
Add((addContainerSize ? sizeof(T) : 0) +
|
||||
(int)vec.capacity() * sizeof(T) +
|
||||
(int)vec.size() * sizeof(typename std::remove_pointer<T>::type)); //-V220
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AddVecPtr(const Array<T>& vec, bool addContainerSize = true)
|
||||
{
|
||||
Add((addContainerSize ? sizeof(T) : 0) +
|
||||
(int)vec.mAllocSize * sizeof(T) +
|
||||
(int)vec.size() * sizeof(typename std::remove_pointer<T>::type)); //-V220
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AddVecPtr(const StringImpl& name, const Array<T>& vec, bool addContainerSize = true)
|
||||
{
|
||||
Add(name, (addContainerSize ? sizeof(T) : 0) +
|
||||
(int)vec.mAllocSize * sizeof(T) +
|
||||
(int)vec.size() * sizeof(typename std::remove_pointer<T>::type)); //-V220
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AddMap(const StringImpl& name, const T& map, bool addContainerSize = true)
|
||||
{
|
||||
Add(name, (addContainerSize ? sizeof(T) : 0) + map.mAllocSize * (sizeof(typename T::EntryPair) + sizeof(typename T::int_cosize)));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AddMap(const T& map, bool addContainerSize = true)
|
||||
{
|
||||
Add((addContainerSize ? sizeof(T) : 0) + map.mAllocSize * (sizeof(typename T::EntryPair) + sizeof(typename T::int_cosize)));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AddHashSet(const StringImpl& name, const T& map, bool addContainerSize = true)
|
||||
{
|
||||
Add(name, (addContainerSize ? sizeof(T) : 0) + map.mAllocSize * (sizeof(typename T::Entry) + sizeof(typename T::int_cosize)));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void AddHashSet(const T& map, bool addContainerSize = true)
|
||||
{
|
||||
Add((addContainerSize ? sizeof(T) : 0) + map.mAllocSize * (sizeof(typename T::Entry) + sizeof(typename T::int_cosize)));
|
||||
}
|
||||
|
||||
void AddStr(const StringImpl& str, bool addContainerSize = true)
|
||||
{
|
||||
Add((addContainerSize ? sizeof(StringImpl) : 0) + (int)str.GetAllocSize());
|
||||
}
|
||||
|
||||
void AddStr(const StringImpl& name, const StringImpl& str, bool addContainerSize = true)
|
||||
{
|
||||
Add(name, (addContainerSize ? sizeof(StringImpl) : 0) + (int)str.GetAllocSize());
|
||||
}
|
||||
|
||||
void EndSection();
|
||||
void Report();
|
||||
|
||||
|
||||
template <typename T>
|
||||
void AddBumpAlloc(const StringImpl& name, const T& alloc)
|
||||
{
|
||||
BeginSection(name);
|
||||
|
||||
int usedSize = alloc.CalcUsedSize();
|
||||
#ifdef BUMPALLOC_TRACKALLOCS
|
||||
|
||||
T* allocPtr = (T*)&alloc;
|
||||
|
||||
int usedSizeLeft = usedSize;
|
||||
|
||||
Array<Entry> entries;
|
||||
for (const auto& kv : allocPtr->mTrackedAllocs)
|
||||
{
|
||||
const char* str = kv.mKey.c_str();
|
||||
BumpAllocTrackedEntry trackedEntry = kv.mValue;
|
||||
|
||||
String name;
|
||||
|
||||
if (strncmp(str, "class ", 6) == 0)
|
||||
name = str + 6;
|
||||
else if (strncmp(str, "struct ", 7) == 0)
|
||||
name = str + 7;
|
||||
else
|
||||
name = str;
|
||||
|
||||
BeginSection(name);
|
||||
mCurEntry->mSize += trackedEntry.mSize;
|
||||
mCurEntry->mCount += trackedEntry.mCount;
|
||||
EndSection();
|
||||
|
||||
usedSizeLeft -= trackedEntry.mSize;
|
||||
}
|
||||
if (usedSizeLeft > 0)
|
||||
Add("Unaccounted", usedSizeLeft);
|
||||
#else
|
||||
Add("Used", usedSize);
|
||||
#endif
|
||||
Add("Waste", alloc.GetAllocSize() - usedSize);
|
||||
Add("Unused", alloc.GetTotalAllocSize() - alloc.GetAllocSize());
|
||||
|
||||
EndSection();
|
||||
}
|
||||
};
|
||||
|
||||
class AutoMemReporter
|
||||
{
|
||||
public:
|
||||
MemReporter* mMemReporter;
|
||||
|
||||
public:
|
||||
AutoMemReporter(MemReporter* memReporter, const StringImpl& name)
|
||||
{
|
||||
mMemReporter = memReporter;
|
||||
mMemReporter->BeginSection(name);
|
||||
}
|
||||
|
||||
~AutoMemReporter()
|
||||
{
|
||||
mMemReporter->EndSection();
|
||||
}
|
||||
};
|
||||
|
||||
NS_BF_END
|
Loading…
Add table
Add a link
Reference in a new issue