1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 04:22:20 +02:00

Added ability to catch llvm errs(), shared crashcatcher object

This commit is contained in:
Brian Fiete 2020-05-28 07:25:25 -07:00
parent 76e29d385b
commit f1eafa8d81
4 changed files with 274 additions and 113 deletions

View file

@ -1,5 +1,4 @@
#include "CrashCatcher.h" #include "CrashCatcher.h"
#include "../util/CritSect.h"
#include "../util/Dictionary.h" #include "../util/Dictionary.h"
#include <commdlg.h> #include <commdlg.h>
#include <time.h> #include <time.h>
@ -51,15 +50,7 @@ static SYMFUNCTIONTABLEACCESSPROC gSymFunctionTableAccess = NULL;
static SYMGETMODULEBASEPROC gSymGetModuleBase = NULL; static SYMGETMODULEBASEPROC gSymGetModuleBase = NULL;
static SYMGETSYMFROMADDRPROC gSymGetSymFromAddr = NULL; static SYMGETSYMFROMADDRPROC gSymGetSymFromAddr = NULL;
static SYMGETLINEFROMADDR gSymGetLineFromAddr = NULL; static SYMGETLINEFROMADDR gSymGetLineFromAddr = NULL;
static Array<CrashInfoFunc> gCrashInfoFuncs;
static StringT<0> gCrashInfo;
static bool gCrashed = false;
extern CritSect gBfpCritSect;
static EXCEPTION_POINTERS* gExceptionPointers = NULL;
static LPTOP_LEVEL_EXCEPTION_FILTER gPreviousFilter = NULL;
static bool gDebugError = false;
static bool CreateMiniDump(EXCEPTION_POINTERS* pep, const StringImpl& filePath); static bool CreateMiniDump(EXCEPTION_POINTERS* pep, const StringImpl& filePath);
@ -162,7 +153,6 @@ struct
{ 0xFFFFFFFF, "" } { 0xFFFFFFFF, "" }
}; };
static bool gUseDefaultFonts;
static HFONT gDialogFont; static HFONT gDialogFont;
static HFONT gBoldFont; static HFONT gBoldFont;
static String gErrorTitle; static String gErrorTitle;
@ -171,7 +161,6 @@ static HWND gDebugButtonWindow = NULL;
static HWND gYesButtonWindow = NULL; static HWND gYesButtonWindow = NULL;
static HWND gNoButtonWindow = NULL; static HWND gNoButtonWindow = NULL;
static bool gExiting = false; static bool gExiting = false;
static BfpCrashReportKind gCrashReportKind = BfpCrashReportKind_Default;
static LRESULT CALLBACK SEHWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) static LRESULT CALLBACK SEHWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
@ -198,7 +187,7 @@ static LRESULT CALLBACK SEHWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
if (::GetSaveFileNameW(&openFileName)) if (::GetSaveFileNameW(&openFileName))
{ {
CreateMiniDump(gExceptionPointers, UTF8Encode(fileName)); CreateMiniDump(CrashCatcher::Get()->mExceptionPointers, UTF8Encode(fileName));
} }
} }
else if (hwndCtl == gNoButtonWindow) else if (hwndCtl == gNoButtonWindow)
@ -207,7 +196,7 @@ static LRESULT CALLBACK SEHWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
} }
else if (hwndCtl == gDebugButtonWindow) else if (hwndCtl == gDebugButtonWindow)
{ {
gDebugError = true; CrashCatcher::Get()->mDebugError = true;
gExiting = true; gExiting = true;
} }
} }
@ -222,6 +211,8 @@ static LRESULT CALLBACK SEHWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
static void ShowErrorDialog(const StringImpl& errorTitle, const StringImpl& errorText) static void ShowErrorDialog(const StringImpl& errorTitle, const StringImpl& errorText)
{ {
bool gUseDefaultFonts;
HINSTANCE gHInstance = ::GetModuleHandle(NULL); HINSTANCE gHInstance = ::GetModuleHandle(NULL);
OSVERSIONINFO aVersionInfo; OSVERSIONINFO aVersionInfo;
@ -247,7 +238,6 @@ static void ShowErrorDialog(const StringImpl& errorTitle, const StringImpl& erro
gErrorTitle = errorTitle; gErrorTitle = errorTitle;
gErrorText = errorText; gErrorText = errorText;
WNDCLASSW wc; WNDCLASSW wc;
wc.style = 0; wc.style = 0;
wc.cbClsExtra = 0; wc.cbClsExtra = 0;
@ -810,18 +800,18 @@ static String GetVersion(const StringImpl& fileName)
static void DoHandleDebugEvent(LPEXCEPTION_POINTERS lpEP) static void DoHandleDebugEvent(LPEXCEPTION_POINTERS lpEP)
{ {
if (gCrashed) if (CrashCatcher::Get()->mCrashed)
return; return;
gCrashed = true; CrashCatcher::Get()->mCrashed = true;
HMODULE hMod = GetModuleHandleA(NULL); HMODULE hMod = GetModuleHandleA(NULL);
PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod; PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod;
PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)((uint8*)hMod + pDosHdr->e_lfanew); PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)((uint8*)hMod + pDosHdr->e_lfanew);
bool isCLI = pNtHdr->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI; bool isCLI = pNtHdr->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI;
if (gCrashReportKind == BfpCrashReportKind_GUI) if (CrashCatcher::Get()->mCrashReportKind == BfpCrashReportKind_GUI)
isCLI = false; isCLI = false;
else if ((gCrashReportKind == BfpCrashReportKind_Console) || (gCrashReportKind == BfpCrashReportKind_PrintOnly)) else if ((CrashCatcher::Get()->mCrashReportKind == BfpCrashReportKind_Console) || (CrashCatcher::Get()->mCrashReportKind == BfpCrashReportKind_PrintOnly))
isCLI = true; isCLI = true;
bool hasImageHelp = LoadImageHelp(); bool hasImageHelp = LoadImageHelp();
@ -859,10 +849,10 @@ static void DoHandleDebugEvent(LPEXCEPTION_POINTERS lpEP)
} }
} }
for (auto func : gCrashInfoFuncs) for (auto func : CrashCatcher::Get()->mCrashInfoFuncs)
func(); func();
aDebugDump.Append(gCrashInfo); aDebugDump.Append(CrashCatcher::Get()->mCrashInfo);
for (int i = 0; i < (int)aDebugDump.length(); i++) for (int i = 0; i < (int)aDebugDump.length(); i++)
{ {
@ -994,26 +984,31 @@ static void DoHandleDebugEvent(LPEXCEPTION_POINTERS lpEP)
CrashCatcher::CrashCatcher() CrashCatcher::CrashCatcher()
{ {
mCrashed = false;
mInitialized = false;
mExceptionPointers = NULL;
mPreviousFilter = NULL;
mDebugError = false;
mCrashReportKind = BfpCrashReportKind_Default;
} }
static long __stdcall SEHFilter(LPEXCEPTION_POINTERS lpExceptPtr) static long __stdcall SEHFilter(LPEXCEPTION_POINTERS lpExceptPtr)
{ {
OutputDebugStrF("SEH Filter! CraskReportKind:%d\n", gCrashReportKind); OutputDebugStrF("SEH Filter! CraskReportKind:%d\n", CrashCatcher::Get()->mCrashReportKind);
if (gCrashReportKind == BfpCrashReportKind_None) if (CrashCatcher::Get()->mCrashReportKind == BfpCrashReportKind_None)
{ {
OutputDebugStrF("Silent Exiting\n"); OutputDebugStrF("Silent Exiting\n");
::TerminateProcess(GetCurrentProcess(), lpExceptPtr->ExceptionRecord->ExceptionCode); ::TerminateProcess(GetCurrentProcess(), lpExceptPtr->ExceptionRecord->ExceptionCode);
} }
AutoCrit autoCrit(gBfpCritSect); AutoCrit autoCrit(CrashCatcher::Get()->mBfpCritSect);
//::ExitProcess(); //::ExitProcess();
//quick_exit(1); //quick_exit(1);
if (!gCrashed) if (!CrashCatcher::Get()->mCrashed)
{ {
gExceptionPointers = lpExceptPtr; CrashCatcher::Get()->mExceptionPointers = lpExceptPtr;
//CreateMiniDump(lpExceptPtr); //CreateMiniDump(lpExceptPtr);
DoHandleDebugEvent(lpExceptPtr); DoHandleDebugEvent(lpExceptPtr);
} }
@ -1021,7 +1016,7 @@ static long __stdcall SEHFilter(LPEXCEPTION_POINTERS lpExceptPtr)
//if (!gDebugError) //if (!gDebugError)
//SetErrorMode(SEM_NOGPFAULTERRORBOX); //SetErrorMode(SEM_NOGPFAULTERRORBOX);
if (gCrashReportKind == BfpCrashReportKind_PrintOnly) if (CrashCatcher::Get()->mCrashReportKind == BfpCrashReportKind_PrintOnly)
{ {
::TerminateProcess(GetCurrentProcess(), lpExceptPtr->ExceptionRecord->ExceptionCode); ::TerminateProcess(GetCurrentProcess(), lpExceptPtr->ExceptionRecord->ExceptionCode);
} }
@ -1040,8 +1035,12 @@ static long __stdcall VectorExceptionHandler(LPEXCEPTION_POINTERS lpExceptPtr)
void CrashCatcher::Init() void CrashCatcher::Init()
{ {
gPreviousFilter = SetUnhandledExceptionFilter(SEHFilter); if (mInitialized)
OutputDebugStrF("Setting SEH filter %p\n", gPreviousFilter); return;
mPreviousFilter = SetUnhandledExceptionFilter(SEHFilter);
OutputDebugStrF("Setting SEH filter %p\n", mPreviousFilter);
mInitialized = true;
// OutputDebugStrF("AddVectoredExceptionHandler 2\n"); // OutputDebugStrF("AddVectoredExceptionHandler 2\n");
// AddVectoredExceptionHandler(0, VectorExceptionHandler); // AddVectoredExceptionHandler(0, VectorExceptionHandler);
@ -1065,30 +1064,33 @@ void CrashCatcher::Test()
void CrashCatcher::AddCrashInfoFunc(CrashInfoFunc crashInfoFunc) void CrashCatcher::AddCrashInfoFunc(CrashInfoFunc crashInfoFunc)
{ {
AutoCrit autoCrit(gBfpCritSect); AutoCrit autoCrit(mBfpCritSect);
gCrashInfoFuncs.Add(crashInfoFunc); mCrashInfoFuncs.Add(crashInfoFunc);
} }
void CrashCatcher::AddInfo(const StringImpl& str) void CrashCatcher::AddInfo(const StringImpl& str)
{ {
AutoCrit autoCrit(gBfpCritSect); AutoCrit autoCrit(mBfpCritSect);
gCrashInfo.Append(str); mCrashInfo.Append(str);
if (!str.EndsWith('\n'))
mCrashInfo.Append('\n');
} }
void CrashCatcher::Crash(const StringImpl& str) void CrashCatcher::Crash(const StringImpl& str)
{ {
OutputDebugStrF("CrashCatcher::Crash\n"); OutputDebugStrF("CrashCatcher::Crash\n");
gBfpCritSect.Lock(); mBfpCritSect.Lock();
gCrashInfo.Append(str); mCrashInfo.Append(str);
mCrashInfo.Append("\n");
if (gPreviousFilter == NULL) if (mPreviousFilter == NULL)
{ {
// A little late, but install handler now so we can catch this crash // A little late, but install handler now so we can catch this crash
Init(); Init();
} }
gBfpCritSect.Unlock(); mBfpCritSect.Unlock();
__debugbreak(); __debugbreak();
@ -1110,5 +1112,68 @@ void CrashCatcher::Crash(const StringImpl& str)
void CrashCatcher::SetCrashReportKind(BfpCrashReportKind crashReportKind) void CrashCatcher::SetCrashReportKind(BfpCrashReportKind crashReportKind)
{ {
gCrashReportKind = crashReportKind; mCrashReportKind = crashReportKind;
}
struct CrashCatchMemory
{
public:
CrashCatcher* mBpManager;
int mABIVersion;
};
#define CRASHCATCH_ABI_VERSION 1
static CrashCatcher* sCrashCatcher = NULL;
CrashCatcher* CrashCatcher::Get()
{
if (sCrashCatcher != NULL)
return sCrashCatcher;
char mutexName[128];
sprintf(mutexName, "BfCrashCatch_mutex_%d", GetCurrentProcessId());
char memName[128];
sprintf(memName, "BfCrashCatch_mem_%d", GetCurrentProcessId());
auto mutex = ::CreateMutexA(NULL, TRUE, mutexName);
if (mutex != NULL)
{
HANDLE fileMapping = ::OpenFileMappingA(FILE_MAP_ALL_ACCESS, FALSE, memName);
if (fileMapping != NULL)
{
CrashCatchMemory* sharedMem = (CrashCatchMemory*)MapViewOfFile(fileMapping, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(CrashCatchMemory));
if (sharedMem != NULL)
{
if (sharedMem->mABIVersion == CRASHCATCH_ABI_VERSION)
sCrashCatcher = sharedMem->mBpManager;
::UnmapViewOfFile(sharedMem);
}
::CloseHandle(fileMapping);
}
else
{
fileMapping = ::CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(CrashCatchMemory), memName);
if (fileMapping != NULL)
{
CrashCatchMemory* sharedMem = (CrashCatchMemory*)MapViewOfFile(fileMapping, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(CrashCatchMemory));
if (sharedMem != NULL)
{
sCrashCatcher = new CrashCatcher();
sharedMem->mBpManager = sCrashCatcher;
sharedMem->mABIVersion = CRASHCATCH_ABI_VERSION;
::UnmapViewOfFile(sharedMem);
::ReleaseMutex(mutex);
}
else
{
::CloseHandle(fileMapping);
::CloseHandle(mutex);
}
}
}
}
if (sCrashCatcher == NULL)
sCrashCatcher = new CrashCatcher();
return sCrashCatcher;
} }

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "../../BeefySysLib/Common.h" #include "../../BeefySysLib/Common.h"
#include "../util/CritSect.h"
NS_BF_BEGIN NS_BF_BEGIN
@ -8,6 +9,17 @@ typedef void(*CrashInfoFunc)();
class CrashCatcher class CrashCatcher
{ {
public:
Array<CrashInfoFunc> mCrashInfoFuncs;
StringT<0> mCrashInfo;
bool mCrashed;
bool mInitialized;
CritSect mBfpCritSect;
EXCEPTION_POINTERS* mExceptionPointers;
LPTOP_LEVEL_EXCEPTION_FILTER mPreviousFilter;
bool mDebugError;
BfpCrashReportKind mCrashReportKind;
public: public:
CrashCatcher(); CrashCatcher();
@ -18,6 +30,8 @@ public:
void Test(); void Test();
void Crash(const StringImpl& str); void Crash(const StringImpl& str);
void SetCrashReportKind(BfpCrashReportKind crashReportKind); void SetCrashReportKind(BfpCrashReportKind crashReportKind);
static CrashCatcher* Get();
}; };
NS_BF_END NS_BF_END

View file

@ -23,8 +23,6 @@
#include "util/AllocDebug.h" #include "util/AllocDebug.h"
//kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
#pragma comment(lib, "ole32.lib") #pragma comment(lib, "ole32.lib")
#pragma comment(lib, "shell32.lib") #pragma comment(lib, "shell32.lib")
#pragma comment(lib, "user32.lib") #pragma comment(lib, "user32.lib")
@ -47,10 +45,6 @@ struct WindowsSharedInfo
static WindowsSharedInfo* gGlobalPlatformInfo = NULL; static WindowsSharedInfo* gGlobalPlatformInfo = NULL;
static HANDLE gGlobalMutex = 0; static HANDLE gGlobalMutex = 0;
static CrashCatcher gCrashCatcher;
//#define HANDLE_TO_BFPFILE(val) ((BfpFile*)(val))
//#define BFPFILE_TO_HANDLE(val) ((HANDLE)(val))
#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004 #define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
typedef LONG KPRIORITY; typedef LONG KPRIORITY;
@ -950,10 +944,9 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flag
// Then we install our abort handler. // Then we install our abort handler.
signal(SIGABRT, &AbortHandler); signal(SIGABRT, &AbortHandler);
gCrashCatcher.Init(); CrashCatcher::Get()->Init();
if ((flags & BfpSystemInitFlag_SilentCrash) != 0) if ((flags & BfpSystemInitFlag_SilentCrash) != 0)
gCrashCatcher.SetCrashReportKind(BfpCrashReportKind_None); CrashCatcher::Get()->SetCrashReportKind(BfpCrashReportKind_None);
} }
} }
@ -964,17 +957,17 @@ BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCommandLine(int argc, char** argv)
BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCrashReportKind(BfpCrashReportKind crashReportKind) BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCrashReportKind(BfpCrashReportKind crashReportKind)
{ {
gCrashCatcher.SetCrashReportKind(crashReportKind); CrashCatcher::Get()->SetCrashReportKind(crashReportKind);
} }
BFP_EXPORT void BFP_CALLTYPE BfpSystem_AddCrashInfoFunc(BfpCrashInfoFunc crashInfoFunc) BFP_EXPORT void BFP_CALLTYPE BfpSystem_AddCrashInfoFunc(BfpCrashInfoFunc crashInfoFunc)
{ {
gCrashCatcher.AddCrashInfoFunc(crashInfoFunc); CrashCatcher::Get()->AddCrashInfoFunc(crashInfoFunc);
} }
BFP_EXPORT void BFP_CALLTYPE BfpSystem_AddCrashInfo(const char* str) BFP_EXPORT void BFP_CALLTYPE BfpSystem_AddCrashInfo(const char* str)
{ {
gCrashCatcher.AddInfo(str); CrashCatcher::Get()->AddInfo(str);
} }
BFP_EXPORT void BFP_CALLTYPE BfpSystem_Shutdown() BFP_EXPORT void BFP_CALLTYPE BfpSystem_Shutdown()
@ -1077,9 +1070,9 @@ BFP_EXPORT uint64 BFP_CALLTYPE BfpSystem_InterlockedCompareExchange64(uint64* pt
BFP_EXPORT void BFP_CALLTYPE BfpSystem_FatalError(const char* error, const char* title) BFP_EXPORT void BFP_CALLTYPE BfpSystem_FatalError(const char* error, const char* title)
{ {
if (title != NULL) if (title != NULL)
gCrashCatcher.Crash(String(title) + "\n" + String(error)); CrashCatcher::Get()->Crash(String(title) + "\n" + String(error));
else else
gCrashCatcher.Crash(error); CrashCatcher::Get()->Crash(error);
} }
BFP_EXPORT void BFP_CALLTYPE BfpSystem_GetCommandLine(char* outStr, int* inOutStrSize, BfpSystemResult* outResult) BFP_EXPORT void BFP_CALLTYPE BfpSystem_GetCommandLine(char* outStr, int* inOutStrSize, BfpSystemResult* outResult)

View file

@ -2,6 +2,8 @@
#include "BfModule.h" #include "BfModule.h"
#include "BeefySysLib/util/BeefPerf.h" #include "BeefySysLib/util/BeefPerf.h"
#include "BeefySysLib/util/Hash.h" #include "BeefySysLib/util/Hash.h"
#include <io.h>
#include <fcntl.h>
#pragma warning(push) #pragma warning(push)
#pragma warning(disable:4141) #pragma warning(disable:4141)
@ -215,6 +217,147 @@ static llvm::Attribute::AttrKind LLVMMapAttribute(BfIRAttribute attr)
return llvm::Attribute::None; return llvm::Attribute::None;
} }
#ifdef BF_PLATFORM_WINDOWS
struct BfTempFile
{
String mContents;
String mFilePath;
CritSect mCritSect;
FILE* mFP;
BfTempFile()
{
mFP = NULL;
}
~BfTempFile()
{
if (mFP != NULL)
fclose(mFP);
if (!mFilePath.IsEmpty())
::DeleteFileW(UTF8Decode(mFilePath).c_str());
}
bool Create()
{
AutoCrit autoCrit(mCritSect);
if (mFP != NULL)
return false;
WCHAR wPath[4096];
wPath[0] = 0;
::GetTempPathW(4096, wPath);
WCHAR wFilePath[4096];
wFilePath[0] = 0;
GetTempFileNameW(wPath, L"bftmp", 0, wFilePath);
mFilePath = UTF8Encode(wFilePath);
mFP = _wfopen(wFilePath, L"w+D");
return mFP != NULL;
}
String GetContents()
{
AutoCrit autoCrit(mCritSect);
if (mFP != NULL)
{
fseek(mFP, 0, SEEK_END);
int size = (int)ftell(mFP);
fseek(mFP, 0, SEEK_SET);
char* str = new char[size];
int readSize = (int)fread(str, 1, size, mFP);
mContents.Append(str, readSize);
delete [] str;
fclose(mFP);
mFP = NULL;
::DeleteFileW(UTF8Decode(mFilePath).c_str());
}
return mContents;
}
};
static BfTempFile gTempFile;
static void AddStdErrCrashInfo()
{
String tempContents = gTempFile.GetContents();
if (!tempContents.IsEmpty())
BfpSystem_AddCrashInfo(tempContents.c_str());
}
#endif
///
BfIRCodeGen::BfIRCodeGen()
{
mStream = NULL;
mBfIRBuilder = NULL;
mNopInlineAsm = NULL;
mAsmObjectCheckAsm = NULL;
mHasDebugLoc = false;
mAttrSet = NULL;
mIRBuilder = NULL;
mDIBuilder = NULL;
mDICompileUnit = NULL;
mActiveFunction = NULL;
mLLVMContext = new llvm::LLVMContext();
mLLVMModule = NULL;
mIsCodeView = false;
mCmdCount = 0;
#ifdef BF_PLATFORM_WINDOWS
if (::GetStdHandle(STD_ERROR_HANDLE) == 0)
{
if (gTempFile.Create())
{
_dup2(fileno(gTempFile.mFP), 2);
BfpSystem_AddCrashInfoFunc(AddStdErrCrashInfo);
}
}
#endif
}
BfIRCodeGen::~BfIRCodeGen()
{
mDebugLoc = llvm::DebugLoc();
mSavedDebugLocs.Clear();
delete mStream;
delete mIRBuilder;
delete mDIBuilder;
delete mLLVMModule;
delete mLLVMContext;
}
void BfIRCodeGen::Fail(const StringImpl& error)
{
if (mFailed)
return;
if (mHasDebugLoc)
{
auto dbgLoc = mIRBuilder->getCurrentDebugLocation();
if (dbgLoc)
{
llvm::DIFile* file = NULL;
if (llvm::DIScope* scope = llvm::dyn_cast<llvm::DIScope>(dbgLoc.getScope()))
{
BfIRCodeGenBase::Fail(StrFormat("%s at line %d:%d in %s/%s", error.c_str(), dbgLoc.getLine(), dbgLoc.getCol(), scope->getDirectory().data(), scope->getFilename().data()));
return;
}
}
}
BfIRCodeGenBase::Fail(error);
}
void BfIRCodeGen::PrintModule() void BfIRCodeGen::PrintModule()
{ {
Beefy::debug_ostream os; Beefy::debug_ostream os;
@ -362,60 +505,6 @@ void BfIRCodeGen::SetResult(int id, llvm::MDNode* md)
mResults.TryAdd(id, entry); mResults.TryAdd(id, entry);
} }
BfIRCodeGen::BfIRCodeGen()
{
mStream = NULL;
mBfIRBuilder = NULL;
mNopInlineAsm = NULL;
mAsmObjectCheckAsm = NULL;
mHasDebugLoc = false;
mAttrSet = NULL;
mIRBuilder = NULL;
mDIBuilder = NULL;
mDICompileUnit = NULL;
mActiveFunction = NULL;
mLLVMContext = new llvm::LLVMContext();
mLLVMModule = NULL;
mIsCodeView = false;
mCmdCount = 0;
}
BfIRCodeGen::~BfIRCodeGen()
{
mDebugLoc = llvm::DebugLoc();
mSavedDebugLocs.Clear();
delete mStream;
delete mIRBuilder;
delete mDIBuilder;
delete mLLVMModule;
delete mLLVMContext;
}
void BfIRCodeGen::Fail(const StringImpl& error)
{
if (mFailed)
return;
if (mHasDebugLoc)
{
auto dbgLoc = mIRBuilder->getCurrentDebugLocation();
if (dbgLoc)
{
llvm::DIFile* file = NULL;
if (llvm::DIScope* scope = llvm::dyn_cast<llvm::DIScope>(dbgLoc.getScope()))
{
BfIRCodeGenBase::Fail(StrFormat("%s at line %d:%d in %s/%s", error.c_str(), dbgLoc.getLine(), dbgLoc.getCol(), scope->getDirectory().data(), scope->getFilename().data()));
return;
}
}
}
BfIRCodeGenBase::Fail(error);
}
void BfIRCodeGen::ProcessBfIRData(const BfSizedArray<uint8>& buffer) void BfIRCodeGen::ProcessBfIRData(const BfSizedArray<uint8>& buffer)
{ {
struct InlineAsmErrorHook struct InlineAsmErrorHook