1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-07-04 15:26:00 +02:00

Initial checkin

This commit is contained in:
Brian Fiete 2019-08-23 11:56:54 -07:00
parent c74712dad9
commit 078564ac9e
3242 changed files with 1616395 additions and 0 deletions

1676
IDEHelper/Compiler/BfAst.cpp Normal file

File diff suppressed because it is too large Load diff

3173
IDEHelper/Compiler/BfAst.h Normal file

File diff suppressed because it is too large Load diff

View 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
}

View 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

File diff suppressed because it is too large Load diff

View 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

File diff suppressed because it is too large Load diff

View 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

File diff suppressed because it is too large Load diff

View 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

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

View 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

File diff suppressed because it is too large Load diff

View 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

File diff suppressed because it is too large Load diff

View 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

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

View 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

File diff suppressed because it is too large Load diff

View 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

File diff suppressed because it is too large Load diff

View 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

File diff suppressed because it is too large Load diff

View 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

View 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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View 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

File diff suppressed because it is too large Load diff

View 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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

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

File diff suppressed because it is too large Load diff

View 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

File diff suppressed because it is too large Load diff

View 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

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

View 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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

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

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

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

View 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

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

View 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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,7 @@
#include "BeefySysLib/Common.h"
#include "BfAst.h"
NS_BF_BEGIN
NS_BF_END

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

View file

@ -0,0 +1,13 @@
#include "BfVarDeclChecker.h"
USING_NS_BF;
BfVarDeclChecker::BfVarDeclChecker()
{
mHasVarDecl = false;
}
void BfVarDeclChecker::Visit(BfVariableDeclaration * binOpExpr)
{
mHasVarDecl = true;
}

View 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

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

View 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