mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
Lost changes
This commit is contained in:
parent
e6c4a95ccd
commit
8e9d7ed4c4
56 changed files with 1579 additions and 794 deletions
|
@ -796,6 +796,13 @@ namespace Beefy.theme.dark
|
|||
mDragKind = .None;
|
||||
}
|
||||
|
||||
if (Math.Abs(dY) < mSelfHeight * 0.21f)
|
||||
{
|
||||
mDragKind = .None;
|
||||
mDragTarget = null;
|
||||
return;
|
||||
}
|
||||
|
||||
delete mCurDragEvent;
|
||||
mCurDragEvent = new DragEvent();
|
||||
mCurDragEvent.mX = x;
|
||||
|
|
|
@ -106,6 +106,24 @@ namespace Beefy.widgets
|
|||
|
||||
extension KeyCode
|
||||
{
|
||||
public bool IsModifier
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (this)
|
||||
{
|
||||
case .LWin,
|
||||
.RWin,
|
||||
.Alt,
|
||||
.Control,
|
||||
.Command:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Result<KeyCode> Parse(StringView str)
|
||||
{
|
||||
if (str.Length == 1)
|
||||
|
|
|
@ -200,7 +200,8 @@ namespace Beefy.widgets
|
|||
{
|
||||
return (mTabbedView.mParentDockingFrame.mParentDockingFrame == null) &&
|
||||
(mTabbedView.mParentDockingFrame.GetDockedWindowCount() == 1) &&
|
||||
(mTabbedView.GetTabCount() == 1);
|
||||
(mTabbedView.GetTabCount() == 1) &&
|
||||
mTabbedView.mAutoClose;
|
||||
}
|
||||
|
||||
void WindowDragLostFocusHandler(BFWindow window, BFWindow newFocus)
|
||||
|
@ -237,7 +238,7 @@ namespace Beefy.widgets
|
|||
300, 500,
|
||||
BFWindowBase.Flags.Border | BFWindowBase.Flags.ThickFrame | BFWindowBase.Flags.Resizable | BFWindowBase.Flags.SysMenu |
|
||||
BFWindowBase.Flags.Caption | BFWindowBase.Flags.Minimize | BFWindowBase.Flags.ToolWindow | BFWindowBase.Flags.TopMost |
|
||||
BFWindowBase.Flags.UseParentMenu,
|
||||
BFWindowBase.Flags.UseParentMenu | BFWindowBase.Flags.Maximize,
|
||||
subFrame);
|
||||
Dock(subFrame, null, DockingFrame.WidgetAlign.Top);
|
||||
//subFrame.AddDockedWidget(fourthTabbedView, null, DockingFrame.WidgetAlign.Left, false);
|
||||
|
@ -288,7 +289,7 @@ namespace Beefy.widgets
|
|||
if ((refWidget != null) && (refWidget.mWidgetWindow != mWidgetWindow) && (mWidgetWindow != null))
|
||||
mWidgetWindow.SetForeground();
|
||||
|
||||
if (mTabbedView.GetTabCount() == 1)
|
||||
if ((mTabbedView.GetTabCount() == 1) && mTabbedView.mAutoClose)
|
||||
{
|
||||
mTabbedView.Dock(frame, refWidget, align);
|
||||
return;
|
||||
|
@ -327,7 +328,7 @@ namespace Beefy.widgets
|
|||
tabbedView.Dock(frame, refWidget, align);
|
||||
}
|
||||
|
||||
if (prevTabbedView.GetTabCount() == 0)
|
||||
if ((prevTabbedView.GetTabCount() == 0) && prevTabbedView.mAutoClose)
|
||||
{
|
||||
prevTabbedView.mParentDockingFrame.RemoveDockedWidget(prevTabbedView);
|
||||
}
|
||||
|
|
|
@ -746,7 +746,7 @@ namespace SDL2
|
|||
public static extern int32 GetDisplayMode(int32 displayIndex, int32 modeIndex, out SDL_DisplayMode mode);
|
||||
|
||||
/* Available in 2.0.5 or higher */
|
||||
[LinkName("SDL_GetDisplayMode")]
|
||||
[LinkName("SDL_GetDisplayUsableBounds")]
|
||||
public static extern int SDL_GetDisplayUsableBounds(int displayIndex, out Rect rect);
|
||||
|
||||
[LinkName("SDL_GetNumDisplayModes")]
|
||||
|
|
|
@ -315,4 +315,4 @@ namespace SDL2
|
|||
int index
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -119,7 +119,8 @@ namespace System.IO
|
|||
DeleteAndNullify!(mTitle);
|
||||
DeleteAndNullify!(mInitialDir);
|
||||
DeleteAndNullify!(mDefaultExt);
|
||||
DeleteAndNullify!(mFileNames);
|
||||
DeleteContainerAndItems!(mFileNames);
|
||||
mFileNames = null;
|
||||
DeleteAndNullify!(mFilter);
|
||||
mFilterIndex = 1;
|
||||
mSupportMultiDottedExtensions = false;
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
#define INITKNOWNFOLDERS
|
||||
#include <guiddef.h>
|
||||
#include <KnownFolders.h>
|
||||
#undef INITKNOWNFOLDERS
|
||||
|
||||
#pragma warning(disable:4065)
|
||||
#pragma warning(disable:4996)
|
||||
|
||||
|
|
|
@ -164,17 +164,30 @@ public:
|
|||
{
|
||||
auto newHashHeads = (Entry**)TFuncs::AllocateZero(sizeof(Entry*) * newHashSize, alignof(Entry*));
|
||||
|
||||
SizedArray<Entry*, 32> entryList;
|
||||
|
||||
for (int hashIdx = 0; hashIdx < mHashSize; hashIdx++)
|
||||
{
|
||||
Entry* checkEntry = mHashHeads[hashIdx];
|
||||
while (checkEntry != NULL)
|
||||
if (checkEntry != NULL)
|
||||
{
|
||||
auto nextEntry = checkEntry->mNext;
|
||||
int newHashIdx = (checkEntry->mHash & 0x7FFFFFFF) % newHashSize;
|
||||
checkEntry->mNext = newHashHeads[newHashIdx];
|
||||
newHashHeads[newHashIdx] = checkEntry;
|
||||
|
||||
checkEntry = nextEntry;
|
||||
// We want to keep elements with equal hashes in their insert order so we need to
|
||||
// iterate through the linked list in reverse
|
||||
entryList.Clear();
|
||||
|
||||
while (checkEntry != NULL)
|
||||
{
|
||||
entryList.Add(checkEntry);
|
||||
checkEntry = checkEntry->mNext;
|
||||
}
|
||||
|
||||
for (int i = (int)entryList.mSize - 1; i >= 0; i--)
|
||||
{
|
||||
auto checkEntry = entryList[i];
|
||||
int newHashIdx = (checkEntry->mHash & 0x7FFFFFFF) % newHashSize;
|
||||
checkEntry->mNext = newHashHeads[newHashIdx];
|
||||
newHashHeads[newHashIdx] = checkEntry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
3
IDE/dist/lib/gen/src/Program.bf
vendored
3
IDE/dist/lib/gen/src/Program.bf
vendored
|
@ -12,7 +12,8 @@ namespace gen
|
|||
{
|
||||
class Program
|
||||
{
|
||||
static String[] sNames = new .[]("comdlg32", "gdi32", "kernel32", "ole32", "netapi32", "ntdll", "rpcrt4", "user32", "version", "winmm") ~ delete _;
|
||||
static String[] sNames = new .[]("advapi32", "comdlg32", "crypt32", "d3d11", "dinput8", "gdi32", "kernel32", "ole32", "netapi32",
|
||||
"ntdll", "rpcrt4", "shell32", "shlwapi", "user32", "version", "winmm", "winhttp", "wininet", "WS2_32", "wsock32") ~ delete _;
|
||||
|
||||
public static int Main(String[] args)
|
||||
{
|
||||
|
|
|
@ -29,12 +29,8 @@ namespace IDE
|
|||
public int32 mUpdateCnt;
|
||||
public Project mHotProject;
|
||||
public Workspace.Options mWorkspaceOptions;
|
||||
public Dictionary<Project, String> mImpLibMap = new .() ~
|
||||
{
|
||||
for (let val in _.Values)
|
||||
delete val;
|
||||
delete _;
|
||||
};
|
||||
public Dictionary<Project, String> mImpLibMap = new .() ~ DeleteDictionaryAndValues!(_);
|
||||
public Dictionary<Project, String> mTargetPathMap = new .() ~ DeleteDictionaryAndValues!(_);
|
||||
public ScriptManager.Context mScriptContext = new .() ~ _.ReleaseLastRef();
|
||||
public ScriptManager mScriptManager ~ delete _;
|
||||
|
||||
|
@ -122,7 +118,7 @@ namespace IDE
|
|||
|
||||
bool didCommands = false;
|
||||
|
||||
let targetName = scope String("Project ", project.mProjectName);
|
||||
//let targetName = scope String("Project ", project.mProjectName);
|
||||
|
||||
//Console.WriteLine("Executing custom command {0} {1} {2}", highestDateTime, targetDateTime, forceRebuild);
|
||||
for (let origCustomCmd in cmdList)
|
||||
|
@ -163,19 +159,13 @@ namespace IDE
|
|||
didCommands = true;
|
||||
}
|
||||
|
||||
mScriptManager.QueueCommands(customCmd, scope String()..AppendF("project {}", project.mProjectName), .NoLines);
|
||||
let scriptCmd = new IDEApp.ScriptCmd();
|
||||
scriptCmd.mCmd = new String(customCmd);
|
||||
scriptCmd.mPath = new $"project {project.mProjectName}";
|
||||
gApp.mExecutionQueue.Add(scriptCmd);
|
||||
continue;
|
||||
}
|
||||
|
||||
let targetCompleteCmd = new IDEApp.TargetCompletedCmd(project);
|
||||
if (didCommands)
|
||||
{
|
||||
mScriptManager.QueueCommands(scope String()..AppendF("%targetComplete {}", project.mProjectName), targetName, .NoLines);
|
||||
targetCompleteCmd.mIsReady = false;
|
||||
project.mNeedsTargetRebuild = true;
|
||||
}
|
||||
gApp.mExecutionQueue.Add(targetCompleteCmd);
|
||||
|
||||
return didCommands ? .HadCommands : .NoCommands;
|
||||
}
|
||||
|
||||
|
@ -874,9 +864,9 @@ namespace IDE
|
|||
minRTModName.Insert(0, "_");
|
||||
|
||||
if (!is64Bit)
|
||||
linkLine.Append("-libpath:\"", gApp.mInstallDir, "lib\\x86\" ", gApp.mInstallDir, "lib\\x86\\msvcrt.lib Beef", IDEApp.sRTVersionStr,"MinRT32", minRTModName, ".lib ");
|
||||
linkLine.Append("-libpath:\"", gApp.mInstallDir, "lib\\x86\" \"", gApp.mInstallDir, "lib\\x86\\msvcrt.lib\" Beef", IDEApp.sRTVersionStr,"MinRT32", minRTModName, ".lib ");
|
||||
else
|
||||
linkLine.Append("-libpath:\"", gApp.mInstallDir, "lib\\x64\" ", gApp.mInstallDir, "lib\\x64\\msvcrt.lib Beef", IDEApp.sRTVersionStr,"MinRT64", minRTModName, ".lib ");
|
||||
linkLine.Append("-libpath:\"", gApp.mInstallDir, "lib\\x64\" \"", gApp.mInstallDir, "lib\\x64\\msvcrt.lib\" Beef", IDEApp.sRTVersionStr,"MinRT64", minRTModName, ".lib ");
|
||||
linkLine.Append("ntdll.lib user32.lib kernel32.lib gdi32.lib winmm.lib shell32.lib ole32.lib rpcrt4.lib version.lib comdlg32.lib -ignore:4049 -ignore:4217 ");
|
||||
}
|
||||
|
||||
|
@ -1062,17 +1052,8 @@ namespace IDE
|
|||
|
||||
IDEUtils.AppendWithOptionalQuotes(linkLine, resOutPath);
|
||||
}
|
||||
|
||||
let binPath = (!is64Bit) ? gApp.mSettings.mVSSettings.mBin32Path : gApp.mSettings.mVSSettings.mBin64Path;
|
||||
if (binPath.IsWhiteSpace)
|
||||
{
|
||||
gApp.OutputErrorLine("Visual Studio tool path not configured. Check Visual Studio configuration in File\\Preferences\\Settings.");
|
||||
return false;
|
||||
}
|
||||
|
||||
String linkerPath = scope String();
|
||||
linkerPath.Append(binPath);
|
||||
linkerPath.Append("/link.exe");
|
||||
if (workspaceOptions.mToolsetType == .LLVM)
|
||||
{
|
||||
linkerPath.Clear();
|
||||
|
@ -1097,6 +1078,17 @@ namespace IDE
|
|||
if ((mPlatformType == .Windows) && (!is64Bit))
|
||||
linkLine.Append(" /safeseh:no");
|
||||
}
|
||||
else
|
||||
{
|
||||
let binPath = (!is64Bit) ? gApp.mSettings.mVSSettings.mBin32Path : gApp.mSettings.mVSSettings.mBin64Path;
|
||||
if (binPath.IsWhiteSpace)
|
||||
{
|
||||
gApp.OutputErrorLine("Visual Studio tool path not configured. Check Visual Studio configuration in File\\Preferences\\Settings.");
|
||||
return false;
|
||||
}
|
||||
linkerPath.Append(binPath);
|
||||
linkerPath.Append("/link.exe");
|
||||
}
|
||||
|
||||
if (options.mBuildOptions.mBeefLibType != .DynamicDebug)
|
||||
{
|
||||
|
@ -1216,6 +1208,8 @@ namespace IDE
|
|||
}
|
||||
}
|
||||
|
||||
mTargetPathMap[project] = new String(targetPath);
|
||||
|
||||
if (hotProject == null)
|
||||
{
|
||||
switch (QueueProjectCustomBuildCommands(project, targetPath, compileKind.WantsRunAfter ? options.mBuildOptions.mBuildCommandsOnRun : options.mBuildOptions.mBuildCommandsOnCompile, options.mBuildOptions.mPreBuildCmds))
|
||||
|
@ -1226,22 +1220,9 @@ namespace IDE
|
|||
completedCompileCmd.mFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
void DoPostBuild()
|
||||
{
|
||||
switch (QueueProjectCustomBuildCommands(project, targetPath, compileKind.WantsRunAfter ? options.mBuildOptions.mBuildCommandsOnRun : options.mBuildOptions.mBuildCommandsOnCompile, options.mBuildOptions.mPostBuildCmds))
|
||||
{
|
||||
case .NoCommands:
|
||||
case .HadCommands:
|
||||
case .Failed:
|
||||
completedCompileCmd.mFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (project.mGeneralOptions.mTargetType == .CustomBuild)
|
||||
{
|
||||
if (hotProject == null)
|
||||
DoPostBuild();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1402,8 +1383,32 @@ namespace IDE
|
|||
return false;
|
||||
}
|
||||
|
||||
DoPostBuild();
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool QueueProjectPostBuild(Project project, Project hotProject, IDEApp.BuildCompletedCmd completedCompileCmd, List<String> hotFileNames, CompileKind compileKind)
|
||||
{
|
||||
if (hotProject != null)
|
||||
return true;
|
||||
|
||||
Project.Options options = gApp.GetCurProjectOptions(project);
|
||||
if (options == null)
|
||||
return true;
|
||||
|
||||
String targetPath = null;
|
||||
mTargetPathMap.TryGetValue(project, out targetPath);
|
||||
if (targetPath == null)
|
||||
return false;
|
||||
|
||||
switch (QueueProjectCustomBuildCommands(project, targetPath, compileKind.WantsRunAfter ? options.mBuildOptions.mBuildCommandsOnRun : options.mBuildOptions.mBuildCommandsOnCompile, options.mBuildOptions.mPostBuildCmds))
|
||||
{
|
||||
case .NoCommands:
|
||||
case .HadCommands:
|
||||
case .Failed:
|
||||
completedCompileCmd.mFailed = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,7 +96,8 @@ namespace IDE.Debugger
|
|||
MemoryAddress = 0x40,
|
||||
MemoryWatch = 0x80,
|
||||
Symbol = 0x100,
|
||||
StepIntoCall = 0x200
|
||||
StepIntoCall = 0x200,
|
||||
RawStr = 0x400,
|
||||
}
|
||||
|
||||
[Reflect]
|
||||
|
|
|
@ -436,6 +436,12 @@ namespace IDE
|
|||
}
|
||||
}
|
||||
|
||||
public class ScriptCmd : ExecutionCmd
|
||||
{
|
||||
public String mCmd ~ delete _;
|
||||
public String mPath ~ delete _;
|
||||
}
|
||||
|
||||
public enum ArgsFileKind
|
||||
{
|
||||
None,
|
||||
|
@ -7447,83 +7453,103 @@ namespace IDE
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var keyState = scope KeyState();
|
||||
keyState.mKeyCode = evt.mKeyCode;
|
||||
keyState.mKeyFlags = evt.mKeyFlags;
|
||||
|
||||
var curKeyMap = mCommands.mKeyMap;
|
||||
bool hadChordState = mKeyChordState != null;
|
||||
if (mKeyChordState != null)
|
||||
curKeyMap = mKeyChordState.mCommandMap;
|
||||
DeleteAndNullify!(mKeyChordState);
|
||||
|
||||
KeyState matchedKey;
|
||||
IDECommandBase commandBase;
|
||||
if (curKeyMap.mMap.TryGet(keyState, out matchedKey, out commandBase))
|
||||
|
||||
if ((mKeyChordState != null) && (evt.mKeyCode.IsModifier))
|
||||
{
|
||||
if (var commandMap = commandBase as CommandMap)
|
||||
{
|
||||
mKeyChordState = new .();
|
||||
mKeyChordState.mCommandMap = commandMap;
|
||||
mKeyChordState.mKeyState = matchedKey;
|
||||
evt.mHandled = true;
|
||||
return;
|
||||
}
|
||||
else if (var command = commandBase as IDECommand)
|
||||
{
|
||||
bool foundMatch = false;
|
||||
if (useFlags != .None)
|
||||
{
|
||||
var checkCommand = command;
|
||||
while (checkCommand != null)
|
||||
{
|
||||
bool matches = checkCommand.mContextFlags == .None;
|
||||
if (checkCommand.mContextFlags.HasFlag(.Editor))
|
||||
matches |= useFlags.HasFlag(.Editor);
|
||||
if (checkCommand.mContextFlags.HasFlag(.MainWindow))
|
||||
matches |= useFlags.HasFlag(.MainWindow);
|
||||
if (checkCommand.mContextFlags.HasFlag(.WorkWindow))
|
||||
matches |= useFlags.HasFlag(.WorkWindow);
|
||||
|
||||
if (matches)
|
||||
{
|
||||
checkCommand.mAction();
|
||||
foundMatch = true;
|
||||
}
|
||||
checkCommand = checkCommand.mNext;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundMatch)
|
||||
{
|
||||
var checkCommand = command;
|
||||
while (checkCommand != null)
|
||||
{
|
||||
if (checkCommand.mContextFlags == .None)
|
||||
{
|
||||
checkCommand.mAction();
|
||||
foundMatch = true;
|
||||
}
|
||||
checkCommand = checkCommand.mNext;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundMatch)
|
||||
{
|
||||
evt.mHandled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Ignore
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not found
|
||||
if (hadChordState)
|
||||
var keyState = scope KeyState();
|
||||
keyState.mKeyCode = evt.mKeyCode;
|
||||
keyState.mKeyFlags = evt.mKeyFlags;
|
||||
|
||||
var curKeyMap = mCommands.mKeyMap;
|
||||
|
||||
bool hadChordState = mKeyChordState != null;
|
||||
if (mKeyChordState != null)
|
||||
curKeyMap = mKeyChordState.mCommandMap;
|
||||
var prevKeyChordState = mKeyChordState;
|
||||
defer delete prevKeyChordState;
|
||||
mKeyChordState = null;
|
||||
|
||||
KeyState matchedKey;
|
||||
IDECommandBase commandBase;
|
||||
|
||||
bool hadMatch = curKeyMap.mMap.TryGet(keyState, out matchedKey, out commandBase);
|
||||
if ((!hadMatch) && (prevKeyChordState != null))
|
||||
{
|
||||
Beep(.Error);
|
||||
evt.mHandled = true;
|
||||
return;
|
||||
// If we have a "Ctrl+A, Ctrl+B" style sequence then also try to match that against "Ctrl+A, B"
|
||||
KeyState rawKeyState = keyState;
|
||||
rawKeyState.mKeyFlags &= ~prevKeyChordState.mKeyState.mKeyFlags;
|
||||
hadMatch = curKeyMap.mMap.TryGet(rawKeyState, out matchedKey, out commandBase);
|
||||
}
|
||||
|
||||
if (hadMatch)
|
||||
{
|
||||
if (var commandMap = commandBase as CommandMap)
|
||||
{
|
||||
mKeyChordState = new .();
|
||||
mKeyChordState.mCommandMap = commandMap;
|
||||
mKeyChordState.mKeyState = matchedKey;
|
||||
evt.mHandled = true;
|
||||
return;
|
||||
}
|
||||
else if (var command = commandBase as IDECommand)
|
||||
{
|
||||
bool foundMatch = false;
|
||||
if (useFlags != .None)
|
||||
{
|
||||
var checkCommand = command;
|
||||
while (checkCommand != null)
|
||||
{
|
||||
bool matches = checkCommand.mContextFlags == .None;
|
||||
if (checkCommand.mContextFlags.HasFlag(.Editor))
|
||||
matches |= useFlags.HasFlag(.Editor);
|
||||
if (checkCommand.mContextFlags.HasFlag(.MainWindow))
|
||||
matches |= useFlags.HasFlag(.MainWindow);
|
||||
if (checkCommand.mContextFlags.HasFlag(.WorkWindow))
|
||||
matches |= useFlags.HasFlag(.WorkWindow);
|
||||
|
||||
if (matches)
|
||||
{
|
||||
checkCommand.mAction();
|
||||
foundMatch = true;
|
||||
}
|
||||
checkCommand = checkCommand.mNext;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundMatch)
|
||||
{
|
||||
var checkCommand = command;
|
||||
while (checkCommand != null)
|
||||
{
|
||||
if (checkCommand.mContextFlags == .None)
|
||||
{
|
||||
checkCommand.mAction();
|
||||
foundMatch = true;
|
||||
}
|
||||
checkCommand = checkCommand.mNext;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundMatch)
|
||||
{
|
||||
evt.mHandled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not found
|
||||
if (hadChordState)
|
||||
{
|
||||
Beep(.Error);
|
||||
evt.mHandled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8256,6 +8282,21 @@ namespace IDE
|
|||
}
|
||||
}
|
||||
|
||||
if (let scriptCmd = next as ScriptCmd)
|
||||
{
|
||||
if (mBuildContext?.mScriptManager != null)
|
||||
{
|
||||
if (scriptCmd.mCmd != null)
|
||||
{
|
||||
mBuildContext.mScriptManager.QueueCommands(scriptCmd.mCmd, scriptCmd.mPath, .NoLines);
|
||||
DeleteAndNullify!(scriptCmd.mCmd);
|
||||
}
|
||||
|
||||
if (mBuildContext.mScriptManager.HasQueuedCommands)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
defer delete next;
|
||||
mExecutionQueue.RemoveAt(0);
|
||||
|
||||
|
@ -8411,6 +8452,11 @@ namespace IDE
|
|||
if (gApp.mDebugger.mIsRunning)
|
||||
mProfilePanel.StartProfiling(profileCmd.mThreadId, profileCmd.mDesc, profileCmd.mSampleRate);
|
||||
}
|
||||
else if (var scriptCmd = next as ScriptCmd)
|
||||
{
|
||||
// Already handled
|
||||
(void)scriptCmd;
|
||||
}
|
||||
else
|
||||
{
|
||||
Runtime.FatalError("Unknown command");
|
||||
|
@ -9163,7 +9209,8 @@ namespace IDE
|
|||
|
||||
public bool DoResolveConfigString(String platformName, Workspace.Options workspaceOptions, Project project, Project.Options options, StringView configString, String error, String result)
|
||||
{
|
||||
int i = result.Length;
|
||||
int startIdx = result.Length;
|
||||
int i = startIdx;
|
||||
result.Append(configString);
|
||||
|
||||
bool hadError = false;
|
||||
|
@ -9258,6 +9305,28 @@ namespace IDE
|
|||
cmdErr = "Invalid number of arguments";
|
||||
case "Var":
|
||||
break ReplaceBlock;
|
||||
case "Arguments",
|
||||
"BuildDir",
|
||||
"LinkFlags",
|
||||
"ProjectDir",
|
||||
"ProjectName",
|
||||
"TargetDir",
|
||||
"TargetPath",
|
||||
"WorkingDir":
|
||||
var selProject = mWorkspace.FindProject(args[0]);
|
||||
if (selProject != null)
|
||||
{
|
||||
Workspace.Options selWorkspaceOptions = gApp.GetCurWorkspaceOptions();
|
||||
Project.Options selOptions = gApp.GetCurProjectOptions(selProject);
|
||||
String selConfigString = scope $"$({cmd})";
|
||||
replaceStr.Clear();
|
||||
newString = scope:ReplaceBlock .();
|
||||
DoResolveConfigString(platformName, selWorkspaceOptions, selProject, selOptions, selConfigString, error, newString);
|
||||
}
|
||||
else
|
||||
cmdErr = "Unable to find project";
|
||||
default:
|
||||
cmdErr = "Invalid command";
|
||||
}
|
||||
|
||||
if (newString == null)
|
||||
|
@ -10251,6 +10320,12 @@ namespace IDE
|
|||
success = false;
|
||||
}
|
||||
|
||||
for (var project in orderedProjectList)
|
||||
{
|
||||
if (!mBuildContext.QueueProjectPostBuild(project, hotProject, completedCompileCmd, hotFileNames, compileKind))
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (hotFileNames.Count > 0)
|
||||
{
|
||||
// Why were we rehupping BEFORE hotLoad?
|
||||
|
@ -10430,6 +10505,36 @@ namespace IDE
|
|||
#endif
|
||||
}
|
||||
|
||||
public bool IsVisualStudioRequired
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Workspace.PlatformType.GetFromName(mPlatformName) != .Windows)
|
||||
return false;
|
||||
var workspaceOptions = GetCurWorkspaceOptions();
|
||||
if (workspaceOptions.mToolsetType != .LLVM)
|
||||
return true;
|
||||
|
||||
for (var project in mWorkspace.mProjects)
|
||||
{
|
||||
if ((project.mGeneralOptions.mTargetType != .BeefConsoleApplication) &&
|
||||
(project.mGeneralOptions.mTargetType != .BeefGUIApplication) &&
|
||||
(project.mGeneralOptions.mTargetType != .BeefApplication_DynamicLib) &&
|
||||
(project.mGeneralOptions.mTargetType != .BeefApplication_StaticLib))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var options = GetCurProjectOptions(project);
|
||||
if (options == null)
|
||||
continue;
|
||||
if (options.mBuildOptions.mCLibType != .SystemMSVCRT)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected bool Compile(CompileKind compileKind = .Normal, Project hotProject = null)
|
||||
{
|
||||
Debug.Assert(mBuildContext == null);
|
||||
|
@ -10604,7 +10709,7 @@ namespace IDE
|
|||
}
|
||||
}
|
||||
|
||||
if (Workspace.PlatformType.GetFromName(mPlatformName) == .Windows)
|
||||
if ((Workspace.PlatformType.GetFromName(mPlatformName) == .Windows) && (IsVisualStudioRequired))
|
||||
{
|
||||
if (!mSettings.mVSSettings.IsConfigured())
|
||||
mSettings.mVSSettings.SetDefaults();
|
||||
|
@ -10788,8 +10893,8 @@ namespace IDE
|
|||
|
||||
//options.mDebugOptions.mCommand
|
||||
|
||||
String launchPath = scope String();
|
||||
ResolveConfigString(mPlatformName, workspaceOptions, project, options, options.mDebugOptions.mCommand, "debug command", launchPath);
|
||||
String launchPathRel = scope String();
|
||||
ResolveConfigString(mPlatformName, workspaceOptions, project, options, options.mDebugOptions.mCommand, "debug command", launchPathRel);
|
||||
String arguments = scope String();
|
||||
ResolveConfigString(mPlatformName, workspaceOptions, project, options, "$(Arguments)", "debug command arguments", arguments);
|
||||
String workingDirRel = scope String();
|
||||
|
@ -10797,6 +10902,9 @@ namespace IDE
|
|||
var workingDir = scope String();
|
||||
Path.GetAbsolutePath(workingDirRel, project.mProjectDir, workingDir);
|
||||
|
||||
String launchPath = scope String();
|
||||
Path.GetAbsolutePath(launchPathRel, workingDir, launchPath);
|
||||
|
||||
String targetPath = scope .();
|
||||
ResolveConfigString(mPlatformName, workspaceOptions, project, options, "$(TargetPath)", "Target path", targetPath);
|
||||
|
||||
|
|
|
@ -1007,7 +1007,7 @@ namespace IDE
|
|||
if (!gApp.[Friend]mExecutionQueue.IsEmpty)
|
||||
{
|
||||
var nextCmd = gApp.mExecutionQueue[0];
|
||||
if (!(nextCmd is IDEApp.TargetCompletedCmd))
|
||||
if (!(nextCmd is IDEApp.ScriptCmd))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -876,16 +876,22 @@ namespace IDE.ui
|
|||
{
|
||||
base.Update();
|
||||
|
||||
if (gApp.mBfResolveCompiler == null)
|
||||
return;
|
||||
|
||||
var focusedItem = (ClassViewListViewItem)mTypeLV.GetRoot().FindFocusedItem();
|
||||
var focusedStr = scope String();
|
||||
if (focusedItem != null)
|
||||
GetName(focusedItem, focusedStr);
|
||||
|
||||
int32 compileRevision = gApp.mBfResolveCompiler.GetCompileRevision();
|
||||
if (mLastCompileRevision != compileRevision)
|
||||
if (gApp.mBfResolveCompiler != null)
|
||||
{
|
||||
mCompileRevisionDirtyDelay = 30;
|
||||
mLastCompileRevision = compileRevision;
|
||||
int32 compileRevision = gApp.mBfResolveCompiler.GetCompileRevision();
|
||||
if (mLastCompileRevision != compileRevision)
|
||||
{
|
||||
mCompileRevisionDirtyDelay = 30;
|
||||
mLastCompileRevision = compileRevision;
|
||||
}
|
||||
}
|
||||
|
||||
if ((mCompileRevisionDirtyDelay > 0) && (--mCompileRevisionDirtyDelay == 0))
|
||||
|
|
|
@ -266,7 +266,7 @@ namespace IDE.ui
|
|||
IdSpan liveCharIdData;
|
||||
String liveText = scope:: String();
|
||||
app.FindProjectSourceContent(projectSource, out liveCharIdData, true, liveText, null);
|
||||
defer(stack) liveCharIdData.Dispose();
|
||||
defer:: liveCharIdData.Dispose();
|
||||
|
||||
var compileInstance = IDEApp.sApp.mWorkspace.GetProjectSourceCompileInstance(projectSource, mHotIdx);
|
||||
if (compileInstance == null)
|
||||
|
|
|
@ -276,7 +276,15 @@ namespace IDE.ui
|
|||
SetLabel(item, codeStr);
|
||||
|
||||
let descItem = item.GetSubItem(1);
|
||||
String errStr = scope String(32)..Append(error.mError);
|
||||
String errStr = scope String(32);
|
||||
int maxLen = 4*1024;
|
||||
if (error.mError.Length > maxLen)
|
||||
{
|
||||
errStr.Append(error.mError.Substring(0, maxLen));
|
||||
errStr.Append("...");
|
||||
}
|
||||
else
|
||||
errStr.Append(error.mError);
|
||||
errStr.Replace('\n', ' ');
|
||||
|
||||
SetLabel(descItem, errStr);
|
||||
|
|
|
@ -718,6 +718,14 @@ namespace IDE.ui
|
|||
var watch = useListViewItem.mWatchEntry;
|
||||
String.NewOrSet!(watch.mName, displayString);
|
||||
String.NewOrSet!(watch.mEvalStr, evalString);
|
||||
|
||||
if (watch.mEvalStr.StartsWith("!raw"))
|
||||
{
|
||||
for (int i < 4)
|
||||
watch.mEvalStr[i] = ' ';
|
||||
watch.mResultType = .RawText;
|
||||
}
|
||||
|
||||
useListViewItem.mWatchEntry = watch;
|
||||
if (!isLiteral)
|
||||
useListViewItem.Label = displayString;
|
||||
|
@ -730,7 +738,7 @@ namespace IDE.ui
|
|||
String val = scope String();
|
||||
if (evalString.StartsWith(":", StringComparison.Ordinal))
|
||||
{
|
||||
var showString = scope String(evalString, 1);
|
||||
var showString = scope String(4096)..Append(evalString, 1);
|
||||
bool isShowingDoc = showString.Contains('\x01');
|
||||
if (!isShowingDoc)
|
||||
{
|
||||
|
@ -759,11 +767,13 @@ namespace IDE.ui
|
|||
flags |= .AllowSideEffects | .AllowCalls;
|
||||
if (gApp.mSettings.mDebuggerSettings.mAutoEvaluateProperties)
|
||||
flags |= .AllowProperties;
|
||||
if (watch.mResultType == .RawText)
|
||||
flags |= .RawStr;
|
||||
|
||||
DebugManager.Language language = mLanguage;
|
||||
if (parentWatchEntry != null)
|
||||
language = parentWatchEntry.mLanguage;
|
||||
gApp.DebugEvaluate(null, evalString, val, -1, language, flags);
|
||||
gApp.DebugEvaluate(null, watch.mEvalStr, val, -1, language, flags);
|
||||
}
|
||||
if (val == "!pending")
|
||||
{
|
||||
|
@ -773,6 +783,13 @@ namespace IDE.ui
|
|||
}
|
||||
watch.mIsPending = false;
|
||||
}
|
||||
|
||||
if (watch.mResultType == .RawText)
|
||||
{
|
||||
String.NewOrSet!(valueSubItem.mLabel, val);
|
||||
return useListViewItem;
|
||||
}
|
||||
|
||||
var vals = scope List<StringView>(val.Split('\n'));
|
||||
|
||||
//if (!vals[0].IsEmpty)
|
||||
|
|
|
@ -7,6 +7,7 @@ using Beefy.theme.dark;
|
|||
using Beefy.gfx;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using IDE.Debugger;
|
||||
|
||||
namespace IDE.ui
|
||||
{
|
||||
|
@ -379,7 +380,11 @@ namespace IDE.ui
|
|||
var subItemLabel = result.GetSubItem(1).mLabel;
|
||||
if (subItemLabel == null)
|
||||
subItemLabel = "";
|
||||
mEditWidgetContent.AppendText(scope String(" ", subItemLabel, "\n"));
|
||||
|
||||
if (result.mWatchEntry.mResultType == .RawText)
|
||||
mEditWidgetContent.AppendText(scope String(subItemLabel, "\n"));
|
||||
else
|
||||
mEditWidgetContent.AppendText(scope String(" ", subItemLabel, "\n"));
|
||||
|
||||
if (result.mWatchEntry.mWarnings != null)
|
||||
{
|
||||
|
@ -415,7 +420,11 @@ namespace IDE.ui
|
|||
for (int32 i = startPos; i < mEditWidgetContent.mData.mTextLength; i++)
|
||||
mEditWidgetContent.mData.mText[i].mDisplayTypeId = (uint8)SourceElementType.Error;
|
||||
}
|
||||
else
|
||||
else if (result.mWatchEntry.mResultType == .RawText)
|
||||
{
|
||||
// No info button
|
||||
}
|
||||
else
|
||||
{
|
||||
mInfoButton.Resize(resultX - GS!(3), resultY - GS!(2), GS!(20), GS!(20));
|
||||
mEditWidgetContent.AddWidget(mInfoButton);
|
||||
|
@ -547,7 +556,16 @@ namespace IDE.ui
|
|||
}
|
||||
else
|
||||
{
|
||||
gApp.DebugEvaluate(null, cmdText, val, mEditWidgetContent.CursorTextPos - mEntryStartPos.mIndex - 2);
|
||||
DebugManager.EvalExpressionFlags flags = .None;
|
||||
|
||||
if (cmdText.StartsWith("!raw"))
|
||||
{
|
||||
for (int i < 4)
|
||||
cmdText[i] = ' ';
|
||||
flags |= .RawStr;
|
||||
}
|
||||
|
||||
gApp.DebugEvaluate(null, cmdText, val, mEditWidgetContent.CursorTextPos - mEntryStartPos.mIndex - 2, .NotSet, flags);
|
||||
gApp.mIsImmediateDebugExprEval = true;
|
||||
}
|
||||
}
|
||||
|
@ -570,7 +588,19 @@ namespace IDE.ui
|
|||
}
|
||||
var info = scope String()..Append(val, idx + ":autocomplete\n".Length);
|
||||
if (!editWidgetContent.mAutoComplete.mIsDocumentationPass)
|
||||
{
|
||||
if ((cmdText.StartsWith("!")) && (!cmdText.Contains(' ')))
|
||||
{
|
||||
if ("!raw".Contains(cmdText))
|
||||
info.Append("cmd\traw\n");
|
||||
if ("!info".Contains(cmdText))
|
||||
info.Append("cmd\tinfo\n");
|
||||
if ("!step".Contains(cmdText))
|
||||
info.Append("cmd\tstep\n");
|
||||
}
|
||||
|
||||
editWidgetContent.mAutoComplete.SetInfo(info, true, mEntryStartPos.mIndex + 1);
|
||||
}
|
||||
}
|
||||
else if (editWidgetContent.mAutoComplete != null)
|
||||
editWidgetContent.mAutoComplete.Close();
|
||||
|
|
|
@ -284,26 +284,20 @@ namespace IDE.ui
|
|||
s.AppendF("0x{:A}", (uint64)lockRange.mBaseOffset);
|
||||
case RepType.Int8:
|
||||
hasAltS = true;
|
||||
(*(int8*)lockRange.mData.CArray()).ToString(s, (altIntBase == 10) ? "" : "X2", null);
|
||||
if (altIntBase == 10)
|
||||
((UInt64)*(uint8*)lockRange.mData.CArray()).ToString(altS, "", null);
|
||||
(*(int8*)lockRange.mData.CArray()).ToString(s, (intBase == 10) ? "" : "X2", null);
|
||||
((UInt64)*(uint8*)lockRange.mData.CArray()).ToString(altS, (altIntBase == 10) ? "" : "X2", null);
|
||||
case RepType.Int16:
|
||||
hasAltS = true;
|
||||
(*(int16*)lockRange.mData.CArray()).ToString(s, (altIntBase == 10) ? "" : "X4", null);
|
||||
if (altIntBase == 10)
|
||||
((UInt64)*(uint16*)lockRange.mData.CArray()).ToString(altS, "", null);
|
||||
(*(int16*)lockRange.mData.CArray()).ToString(s, (intBase == 10) ? "" : "X4", null);
|
||||
((UInt64)*(uint16*)lockRange.mData.CArray()).ToString(altS, (altIntBase == 10) ? "" : "X4", null);
|
||||
case RepType.Int32:
|
||||
hasAltS = true;
|
||||
(*(int32*)lockRange.mData.CArray()).ToString(s, (altIntBase == 10) ? "" : "X8", null);
|
||||
if (altIntBase == 10)
|
||||
((UInt64)*(uint32*)lockRange.mData.CArray()).ToString(altS, "", null);
|
||||
(*(int32*)lockRange.mData.CArray()).ToString(s, (intBase == 10) ? "" : "X8", null);
|
||||
((UInt64)*(uint32*)lockRange.mData.CArray()).ToString(altS, (altIntBase == 10) ? "" : "X8", null);
|
||||
case RepType.Int64:
|
||||
hasAltS = true;
|
||||
(*(int64*)lockRange.mData.CArray()).ToString(s, (altIntBase == 10) ? "" : "X16", null);
|
||||
if (altIntBase == 0x10)
|
||||
s.Insert(8, '\'');
|
||||
if (altIntBase == 10)
|
||||
((UInt64)*(uint64*)lockRange.mData.CArray()).ToString(altS, "", null);
|
||||
(*(int64*)lockRange.mData.CArray()).ToString(s, (intBase == 10) ? "" : "X16", null);
|
||||
((UInt64)*(uint64*)lockRange.mData.CArray()).ToString(altS, (altIntBase == 10) ? "" : "X16", null);
|
||||
case RepType.Float:
|
||||
(*(float*)lockRange.mData.CArray()).ToString(s);
|
||||
case RepType.Double:
|
||||
|
|
|
@ -187,9 +187,10 @@ namespace IDE.ui
|
|||
{
|
||||
base.FocusForKeyboard();
|
||||
SetFocus();
|
||||
if (mListView.GetRoot().FindFocusedItem() == null)
|
||||
let root = mListView.GetRoot();
|
||||
if (root.IsOpen && root.FindFocusedItem() == null)
|
||||
{
|
||||
mListView.GetRoot().GetChildAtIndex(0).Focused = true;
|
||||
root.GetChildAtIndex(0).Focused = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1244,7 +1244,7 @@ namespace IDE.ui
|
|||
{
|
||||
var undoBatchStart = new UndoBatchStart("pasteText");
|
||||
mData.mUndoManager.Add(undoBatchStart);
|
||||
defer(stack) mData.mUndoManager.Add(undoBatchStart.mBatchEnd);
|
||||
defer:: mData.mUndoManager.Add(undoBatchStart.mBatchEnd);
|
||||
}
|
||||
|
||||
if (HasSelection())
|
||||
|
@ -3644,7 +3644,7 @@ namespace IDE.ui
|
|||
|
||||
bool hadSuggestion = false;
|
||||
List<String> suggestions = scope List<String>();
|
||||
defer (scope) ClearAndDeleteItems(suggestions);
|
||||
defer ClearAndDeleteItems(suggestions);
|
||||
spellChecker.GetSuggestions(word, suggestions);
|
||||
for (var suggestion in suggestions)
|
||||
{
|
||||
|
@ -3789,7 +3789,7 @@ namespace IDE.ui
|
|||
else if (bfSystem != null)
|
||||
{
|
||||
parser = bfSystem.CreateEmptyParser(null);
|
||||
defer(stack) delete parser;
|
||||
defer:: delete parser;
|
||||
var text = scope String();
|
||||
mEditWidget.GetText(text);
|
||||
parser.SetSource(text, mSourceViewPanel.mFilePath);
|
||||
|
|
|
@ -5073,7 +5073,11 @@ namespace IDE.ui
|
|||
String showMouseoverString = null;
|
||||
if (bestError.mError != null)
|
||||
{
|
||||
showMouseoverString = scope:: String(":", bestError.mError);
|
||||
int maxLen = 16*1024;
|
||||
if (bestError.mError.Length > maxLen)
|
||||
showMouseoverString = scope:: String()..Concat(":", StringView(bestError.mError, 0, maxLen), "...");
|
||||
else
|
||||
showMouseoverString = scope:: String()..Concat(":", bestError.mError);
|
||||
|
||||
if (bestError.mMoreInfo != null)
|
||||
{
|
||||
|
@ -5676,7 +5680,8 @@ namespace IDE.ui
|
|||
}
|
||||
}
|
||||
|
||||
UpdateMouseover();
|
||||
if (gApp.mIsUpdateBatchStart)
|
||||
UpdateMouseover();
|
||||
|
||||
var compiler = ResolveCompiler;
|
||||
var bfSystem = BfResolveSystem;
|
||||
|
|
|
@ -27,7 +27,8 @@ namespace IDE.ui
|
|||
TypeClass = 0x80,
|
||||
TypeValueType = 0x100,
|
||||
Namespace = 0x200,
|
||||
Text = 0x400
|
||||
Text = 0x400,
|
||||
RawText = 0x800
|
||||
}
|
||||
|
||||
public class WatchEntry
|
||||
|
@ -1740,6 +1741,7 @@ namespace IDE.ui
|
|||
evt.mDragKind = .After;
|
||||
dragTarget = (WatchListViewItem)dragTarget.mParentItem;
|
||||
evt.mDragTarget = dragTarget;
|
||||
return;
|
||||
}
|
||||
if ((dragTarget.mLabel == "") && (dragKind == .After))
|
||||
dragKind = .Before;
|
||||
|
|
|
@ -690,6 +690,8 @@ void BeIRCodeGen::Read(BeValue*& beValue)
|
|||
CMD_PARAM(BeConstant*, initializer);
|
||||
CMD_PARAM(String, name);
|
||||
CMD_PARAM(bool, isTLS);
|
||||
|
||||
BF_ASSERT(varType != NULL);
|
||||
|
||||
auto globalVariable = mBeModule->mGlobalVariables.Alloc();
|
||||
globalVariable->mModule = mBeModule;
|
||||
|
@ -1906,7 +1908,9 @@ void BeIRCodeGen::HandleNextCmd()
|
|||
CMD_PARAM(StringT<256>, name);
|
||||
CMD_PARAM(bool, isTLS);
|
||||
CMD_PARAM(BeConstant*, initializer);
|
||||
|
||||
|
||||
BF_ASSERT(varType != NULL);
|
||||
|
||||
auto globalVariable = mBeModule->mGlobalVariables.Alloc();
|
||||
globalVariable->mModule = mBeModule;
|
||||
globalVariable->mType = varType;
|
||||
|
|
|
@ -3787,7 +3787,7 @@ BeMCOperand BeMCContext::AllocVirtualReg(BeType* type, int refCount, bool mustBe
|
|||
|
||||
if (mDebugging)
|
||||
{
|
||||
if (mcOperand.mVRegIdx == 6)
|
||||
if (mcOperand.mVRegIdx == 227)
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
@ -10364,7 +10364,7 @@ bool BeMCContext::DoLegalization()
|
|||
inst->mArg0.mKind = BeMCOperandKind_SymbolAddr;
|
||||
}
|
||||
|
||||
ReplaceWithNewVReg(inst->mArg0, movInstIdx, true, false);
|
||||
ReplaceWithNewVReg(inst->mArg0, movInstIdx, true, false, true);
|
||||
auto vregInfo = GetVRegInfo(inst->mArg0);
|
||||
vregInfo->mDisableR11 = true;
|
||||
instIdx += 2;
|
||||
|
@ -15842,7 +15842,7 @@ void BeMCContext::Generate(BeFunction* function)
|
|||
mDbgPreferredRegs[32] = X64Reg_R8;*/
|
||||
|
||||
//mDbgPreferredRegs[8] = X64Reg_RAX;
|
||||
//mDebugging = (function->mName == "?ParseRegex@Program@Regex@bf@@CAPEAV?$List@?AUStringView@System@bf@@@Collections@System@3@UStringView@63@0@Z");
|
||||
//mDebugging = (function->mName == "?Zoips@TestProgram@BeefTest@bf@@SAXXZ");
|
||||
// || (function->mName == "?MethodA@TestProgram@BeefTest@bf@@CAXXZ");
|
||||
// || (function->mName == "?Hey@Blurg@bf@@SAXXZ")
|
||||
// ;
|
||||
|
|
|
@ -439,7 +439,8 @@ void BfCodeGenThread::RunLoop()
|
|||
errorMsg += "\n";
|
||||
errorMsg += "Failed writing IR '" + fileName + "': " + ec.message();
|
||||
}
|
||||
fs.WriteSNZ(str);
|
||||
else
|
||||
fs.WriteSNZ(str);
|
||||
}
|
||||
|
||||
if (!hasCacheMatch)
|
||||
|
|
|
@ -341,11 +341,10 @@ BfCompiler::HotResolveData::~HotResolveData()
|
|||
|
||||
BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
||||
{
|
||||
//llvm::DebugFlag = true;
|
||||
|
||||
memset(&mStats, 0, sizeof(mStats));
|
||||
mCompletionPct = 0;
|
||||
mCanceling = false;
|
||||
mHasRequiredTypes = false;
|
||||
mNeedsFullRefresh = false;
|
||||
mFastFinish = false;
|
||||
mHasQueuedTypeRebuilds = false;
|
||||
|
@ -399,6 +398,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
|||
mDbgRawAllocDataTypeDef = NULL;
|
||||
mDeferredCallTypeDef = NULL;
|
||||
mDelegateTypeDef = NULL;
|
||||
mFunctionTypeDef = NULL;
|
||||
mActionTypeDef = NULL;
|
||||
mEnumTypeDef = NULL;
|
||||
mFriendAttributeTypeDef = NULL;
|
||||
|
@ -406,8 +406,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
|||
mConstEvalAttributeTypeDef = NULL;
|
||||
mNoExtensionAttributeTypeDef = NULL;
|
||||
mCheckedAttributeTypeDef = NULL;
|
||||
mUncheckedAttributeTypeDef = NULL;
|
||||
mFunctionTypeDef = NULL;
|
||||
mUncheckedAttributeTypeDef = NULL;
|
||||
mGCTypeDef = NULL;
|
||||
mGenericIEnumerableTypeDef = NULL;
|
||||
mGenericIEnumeratorTypeDef = NULL;
|
||||
|
@ -2146,7 +2145,7 @@ void BfCompiler::UpdateDependencyMap(bool deleteUnusued, bool& didWork)
|
|||
madeFullPass = false;
|
||||
if ((mResolvePassData != NULL) && (mResolvePassData->mParser != NULL))
|
||||
madeFullPass = false;
|
||||
|
||||
|
||||
SetAndRestoreValue<bool> prevAssertOnPopulateType(mContext->mAssertOnPopulateType, deleteUnusued && madeFullPass);
|
||||
|
||||
if ((deleteUnusued) && (madeFullPass))
|
||||
|
@ -5107,6 +5106,18 @@ void BfCompiler::MarkStringPool(BfModule* module)
|
|||
stringPoolEntry.mLastUsedRevision = mRevision;
|
||||
}
|
||||
|
||||
for (int stringId : module->mUnreifiedStringPoolRefs)
|
||||
{
|
||||
BfStringPoolEntry& stringPoolEntry = module->mContext->mStringObjectIdMap[stringId];
|
||||
stringPoolEntry.mLastUsedRevision = mRevision;
|
||||
}
|
||||
|
||||
for (int stringId : module->mImportFileNames)
|
||||
{
|
||||
BfStringPoolEntry& stringPoolEntry = module->mContext->mStringObjectIdMap[stringId];
|
||||
stringPoolEntry.mLastUsedRevision = mRevision;
|
||||
}
|
||||
|
||||
/*if (module->mOptModule != NULL)
|
||||
MarkStringPool(module->mOptModule);*/
|
||||
auto altModule = module->mNextAltModule;
|
||||
|
@ -5220,7 +5231,7 @@ int BfCompiler::GetVTableMethodOffset()
|
|||
bool BfCompiler::DoWorkLoop(bool onlyReifiedTypes, bool onlyReifiedMethods)
|
||||
{
|
||||
bool hadAnyWork = false;
|
||||
|
||||
|
||||
while (true)
|
||||
{
|
||||
bool didWork = false;
|
||||
|
@ -6596,7 +6607,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
|
||||
BpEnter("Compile_Start");
|
||||
|
||||
bool hasRequiredTypes = true;
|
||||
mHasRequiredTypes = true;
|
||||
|
||||
//HashSet<BfTypeDef*> internalTypeDefs;
|
||||
|
||||
|
@ -6606,7 +6617,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
if (typeDef == NULL)
|
||||
{
|
||||
mPassInstance->Fail(StrFormat("Unable to find system type: %s", typeName.c_str()));
|
||||
hasRequiredTypes = false;
|
||||
mHasRequiredTypes = false;
|
||||
}
|
||||
return typeDef;
|
||||
};
|
||||
|
@ -6654,6 +6665,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
mDbgRawAllocDataTypeDef = _GetRequiredType("System.DbgRawAllocData");
|
||||
mDeferredCallTypeDef = _GetRequiredType("System.DeferredCall");
|
||||
mDelegateTypeDef = _GetRequiredType("System.Delegate");
|
||||
mFunctionTypeDef = _GetRequiredType("System.Function");
|
||||
mActionTypeDef = _GetRequiredType("System.Action");
|
||||
mEnumTypeDef = _GetRequiredType("System.Enum");
|
||||
mFriendAttributeTypeDef = _GetRequiredType("System.FriendAttribute");
|
||||
|
@ -6662,8 +6674,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
mNoExtensionAttributeTypeDef = _GetRequiredType("System.NoExtensionAttribute");
|
||||
mCheckedAttributeTypeDef = _GetRequiredType("System.CheckedAttribute");
|
||||
mUncheckedAttributeTypeDef = _GetRequiredType("System.UncheckedAttribute");
|
||||
mResultTypeDef = _GetRequiredType("System.Result", 1);
|
||||
mFunctionTypeDef = _GetRequiredType("System.Function");
|
||||
mResultTypeDef = _GetRequiredType("System.Result", 1);
|
||||
mGCTypeDef = _GetRequiredType("System.GC");
|
||||
mGenericIEnumerableTypeDef = _GetRequiredType("System.Collections.IEnumerable", 1);
|
||||
mGenericIEnumeratorTypeDef = _GetRequiredType("System.Collections.IEnumerator", 1);
|
||||
|
@ -6722,21 +6733,17 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
mContext->mBfTypeType = NULL;
|
||||
mContext->mBfClassVDataPtrType = NULL;
|
||||
|
||||
if (!hasRequiredTypes)
|
||||
{
|
||||
// Force rebuilding
|
||||
BfLogSysM("Compile missing required types\n");
|
||||
mInInvalidState = true;
|
||||
mOptions.mForceRebuildIdx++;
|
||||
return true;
|
||||
}
|
||||
if (!mHasRequiredTypes)
|
||||
{
|
||||
// Force rebuilding
|
||||
BfLogSysM("Compile missing required types\n");
|
||||
mOptions.mForceRebuildIdx++;
|
||||
}
|
||||
|
||||
mSystem->CheckLockYield();
|
||||
|
||||
mContext->mScratchModule->ResolveTypeDef(mBfObjectTypeDef);
|
||||
VisitSourceExteriorNodes();
|
||||
|
||||
//BF_ASSERT(hasRequiredTypes);
|
||||
VisitSourceExteriorNodes();
|
||||
|
||||
if (!mIsResolveOnly)
|
||||
{
|
||||
|
@ -6811,19 +6818,14 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
|
||||
if (mIsResolveOnly)
|
||||
VisitAutocompleteExteriorIdentifiers();
|
||||
|
||||
if (!hasRequiredTypes)
|
||||
{
|
||||
BfLogSysM("Missing required types\n");
|
||||
}
|
||||
|
||||
|
||||
mStats.mTypesQueued = 0;
|
||||
mStats.mMethodsQueued = 0;
|
||||
|
||||
mStats.mTypesQueued += (int)mContext->mPopulateTypeWorkList.size();
|
||||
mStats.mMethodsQueued += (int)mContext->mMethodWorkList.size();
|
||||
|
||||
if (hasRequiredTypes)
|
||||
//
|
||||
{
|
||||
mContext->mScratchModule->ResolveTypeDef(mBfObjectTypeDef, BfPopulateType_Full);
|
||||
|
||||
|
@ -6864,9 +6866,8 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasRequiredTypes)
|
||||
ProcessPurgatory(true);
|
||||
|
||||
ProcessPurgatory(true);
|
||||
|
||||
// Mark used modules
|
||||
if ((mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_AlwaysInclude) && (!mCanceling))
|
||||
|
@ -6967,7 +6968,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
}
|
||||
|
||||
// Generate slot nums
|
||||
if ((!mIsResolveOnly) && (hasRequiredTypes) && (!mCanceling))
|
||||
if ((!mIsResolveOnly) && (!mCanceling))
|
||||
{
|
||||
if ((!IsHotCompile()) || (mHotState->mHasNewInterfaceTypes))
|
||||
{
|
||||
|
@ -6996,7 +6997,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DoWorkLoop();
|
||||
|
||||
BfLogSysM("Compile QueueUnused\n");
|
||||
|
@ -7098,13 +7099,12 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
{
|
||||
DoWorkLoop();
|
||||
}
|
||||
|
||||
if (hasRequiredTypes)
|
||||
ProcessPurgatory(false);
|
||||
|
||||
ProcessPurgatory(false);
|
||||
|
||||
// Old Mark used modules
|
||||
|
||||
if ((!mIsResolveOnly) && (hasRequiredTypes))
|
||||
if (!mIsResolveOnly)
|
||||
{
|
||||
// if ((!mPassInstance->HasFailed()) && (!mCanceling))
|
||||
// {
|
||||
|
@ -7161,7 +7161,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
|
||||
String moduleListStr;
|
||||
int numModulesWritten = 0;
|
||||
if ((hasRequiredTypes) && (!mCanceling))
|
||||
if (!mCanceling)
|
||||
{
|
||||
if (!mIsResolveOnly)
|
||||
{
|
||||
|
@ -7250,9 +7250,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
//printf("Compile done, waiting for finish\n");
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (!hasRequiredTypes)
|
||||
break;
|
||||
{
|
||||
if (mCanceling)
|
||||
mCodeGen.Cancel();
|
||||
bool isDone = mCodeGen.Finish();
|
||||
|
@ -7391,8 +7389,8 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
// gBEMemReporter.Report();
|
||||
// int memReporterSize = gBEMemReporterSize;
|
||||
|
||||
mLastRevisionAborted = mCanceling || !hasRequiredTypes;
|
||||
bool didCancel = mCanceling && hasRequiredTypes;
|
||||
mLastRevisionAborted = mCanceling;
|
||||
bool didCancel = mCanceling;
|
||||
mCanceling = false;
|
||||
|
||||
mContext->ValidateDependencies();
|
||||
|
@ -8961,9 +8959,10 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetTypeInfo(BfCompiler* bfCompiler,
|
|||
SetAndRestoreValue<bool> prevIgnoreWarnings(bfCompiler->mContext->mScratchModule->mIgnoreWarnings, true);
|
||||
SetAndRestoreValue<BfResolvePassData*> prevResolvePass(bfCompiler->mResolvePassData, &resolvePass);
|
||||
|
||||
auto type = bfCompiler->mContext->mScratchModule->ResolveTypeRef(typeRef, BfPopulateType_Data, BfResolveTypeRefFlag_NoCreate);
|
||||
auto type = bfCompiler->mContext->mScratchModule->ResolveTypeRef(typeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_NoCreate);
|
||||
if (type != NULL)
|
||||
{
|
||||
bfCompiler->mContext->mScratchModule->PopulateType(type);
|
||||
outString += "Found";
|
||||
if (auto typeInst = type->ToTypeInstance())
|
||||
{
|
||||
|
|
|
@ -323,6 +323,7 @@ public:
|
|||
BfCodeGen mCodeGen;
|
||||
String mOutputDirectory;
|
||||
bool mCanceling;
|
||||
bool mHasRequiredTypes;
|
||||
bool mNeedsFullRefresh;
|
||||
bool mFastFinish;
|
||||
bool mHasQueuedTypeRebuilds; // Infers we had a fast finish that requires a type rebuild
|
||||
|
@ -352,14 +353,14 @@ public:
|
|||
BfTypeDef* mDbgRawAllocDataTypeDef;
|
||||
BfTypeDef* mDeferredCallTypeDef;
|
||||
BfTypeDef* mDelegateTypeDef;
|
||||
BfTypeDef* mFunctionTypeDef;
|
||||
BfTypeDef* mActionTypeDef;
|
||||
BfTypeDef* mEnumTypeDef;
|
||||
BfTypeDef* mStringTypeDef;
|
||||
BfTypeDef* mStringViewTypeDef;
|
||||
BfTypeDef* mTypeTypeDef;
|
||||
BfTypeDef* mValueTypeTypeDef;
|
||||
BfTypeDef* mResultTypeDef;
|
||||
BfTypeDef* mFunctionTypeDef;
|
||||
BfTypeDef* mResultTypeDef;
|
||||
BfTypeDef* mGCTypeDef;
|
||||
BfTypeDef* mGenericIEnumerableTypeDef;
|
||||
BfTypeDef* mGenericIEnumeratorTypeDef;
|
||||
|
|
|
@ -35,7 +35,7 @@ BfConstResolver::BfConstResolver(BfModule* bfModule) : BfExprEvaluator(bfModule)
|
|||
}
|
||||
|
||||
BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfConstResolveFlags flags)
|
||||
{
|
||||
{
|
||||
mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_Comptime);
|
||||
|
||||
// Handle the 'int[?] val = .(1, 2, 3)' case
|
||||
|
@ -137,11 +137,11 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
|
|||
int stringId = mModule->GetStringPoolIdx(mResult.mValue);
|
||||
if (stringId != -1)
|
||||
{
|
||||
if ((flags & BfConstResolveFlag_RemapFromStringId) != 0)
|
||||
if ((flags & BfConstResolveFlag_ActualizeValues) != 0)
|
||||
{
|
||||
prevIgnoreWrites.Restore();
|
||||
mModule->mBfIRBuilder->PopulateType(mResult.mType);
|
||||
return BfTypedValue(mModule->GetStringObjectValue(stringId), mResult.mType);
|
||||
return BfTypedValue(mModule->GetStringObjectValue(stringId, false, true), mResult.mType);
|
||||
}
|
||||
|
||||
return BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_StringId, stringId), toType);
|
||||
|
@ -232,7 +232,9 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
|
|||
}*/
|
||||
|
||||
mModule->FixIntUnknown(mResult);
|
||||
mModule->FixValueActualization(mResult);
|
||||
|
||||
if ((flags & BfConstResolveFlag_NoActualizeValues) == 0)
|
||||
mModule->FixValueActualization(mResult, !prevIgnoreWrites.mPrevVal || ((flags & BfConstResolveFlag_ActualizeValues) != 0));
|
||||
|
||||
return mResult;
|
||||
}
|
||||
|
@ -416,15 +418,22 @@ bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatch
|
|||
}
|
||||
else
|
||||
{
|
||||
if ((argValue.mValue.IsFake()) && (!argValue.mType->IsValuelessType()))
|
||||
{
|
||||
if ((mModule->mCurMethodInstance == NULL) || (mModule->mCurMethodInstance->mMethodDef->mMethodType != BfMethodType_Mixin))
|
||||
{
|
||||
mModule->Fail("Expression does not evaluate to a constant value", argExpr);
|
||||
}
|
||||
bool requiresConst = false;
|
||||
if ((mModule->mCurMethodInstance == NULL) || (mModule->mCurMethodInstance->mMethodDef->mMethodType != BfMethodType_Mixin))
|
||||
requiresConst = true;
|
||||
|
||||
if ((requiresConst) && (argValue.mValue.IsFake()) && (!argValue.mType->IsValuelessType()))
|
||||
{
|
||||
mModule->Fail("Expression does not evaluate to a constant value", argExpr);
|
||||
}
|
||||
|
||||
llvmArgs.push_back(argValue.mValue);
|
||||
if (!argValue.mType->IsVar())
|
||||
{
|
||||
if ((!requiresConst) || (argValue.mValue.IsConst()) || (argValue.mType->IsValuelessType()))
|
||||
llvmArgs.push_back(argValue.mValue);
|
||||
else
|
||||
llvmArgs.push_back(mModule->GetDefaultValue(argValue.mType));
|
||||
}
|
||||
paramIdx++;
|
||||
}
|
||||
argIdx++;
|
||||
|
|
|
@ -15,9 +15,10 @@ enum BfConstResolveFlags
|
|||
BfConstResolveFlag_ExplicitCast = 1,
|
||||
BfConstResolveFlag_NoCast = 2,
|
||||
BfConstResolveFlag_AllowSoftFail = 4,
|
||||
BfConstResolveFlag_RemapFromStringId = 8,
|
||||
BfConstResolveFlag_ArrayInitSize = 0x10,
|
||||
BfConstResolveFlag_AllowGlobalVariable = 0x20,
|
||||
BfConstResolveFlag_ActualizeValues = 8,
|
||||
BfConstResolveFlag_NoActualizeValues = 0x10,
|
||||
BfConstResolveFlag_ArrayInitSize = 0x20,
|
||||
BfConstResolveFlag_AllowGlobalVariable = 0x40,
|
||||
};
|
||||
|
||||
class BfConstResolver : public BfExprEvaluator
|
||||
|
@ -33,7 +34,7 @@ public:
|
|||
BfConstResolver(BfModule* bfModule);
|
||||
|
||||
BfTypedValue Resolve(BfExpression* expr, BfType* wantType = NULL, BfConstResolveFlags flags = BfConstResolveFlag_None);
|
||||
bool PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatcher* methodMatcher, Array<BfIRValue>& llvmArgs);
|
||||
bool PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatcher* methodMatcher, Array<BfIRValue>& llvmArgs);
|
||||
};
|
||||
|
||||
NS_BF_END
|
|
@ -829,8 +829,7 @@ void BfContext::ValidateDependencies()
|
|||
void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuildModule, bool placeSpecializiedInPurgatory)
|
||||
{
|
||||
BfTypeInstance* typeInst = type->ToTypeInstance();
|
||||
|
||||
|
||||
|
||||
if (type->IsDeleting())
|
||||
{
|
||||
return;
|
||||
|
@ -2517,11 +2516,6 @@ void BfContext::QueueMethodSpecializations(BfTypeInstance* typeInst, bool checkS
|
|||
|
||||
BP_ZONE("BfContext::QueueMethodSpecializations");
|
||||
|
||||
if (typeInst->mTypeId == 578)
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
||||
auto module = typeInst->mModule;
|
||||
if (module == NULL)
|
||||
return;
|
||||
|
@ -2917,10 +2911,21 @@ void BfContext::Cleanup()
|
|||
|
||||
// Clean up deleted BfTypes
|
||||
// These need to get deleted before the modules because we access mModule in the MethodInstance dtors
|
||||
for (auto type : mTypeGraveyard)
|
||||
for (int pass = 0; pass < 2; pass++)
|
||||
{
|
||||
BF_ASSERT(type->mRebuildFlags & BfTypeRebuildFlag_Deleted);
|
||||
delete type;
|
||||
for (int i = 0; i < (int)mTypeGraveyard.size(); i++)
|
||||
{
|
||||
auto type = mTypeGraveyard[i];
|
||||
if (type == NULL)
|
||||
continue;
|
||||
bool deleteNow = (type->IsBoxed() == (pass == 0));
|
||||
if (!deleteNow)
|
||||
continue;
|
||||
|
||||
BF_ASSERT(type->mRebuildFlags & BfTypeRebuildFlag_Deleted);
|
||||
delete type;
|
||||
mTypeGraveyard[i] = NULL;
|
||||
}
|
||||
}
|
||||
mTypeGraveyard.Clear();
|
||||
|
||||
|
|
|
@ -143,10 +143,11 @@ public:
|
|||
|
||||
BfPopulateType mPopulateType;
|
||||
BfTypeReference* mCurBaseTypeRef;
|
||||
BfTypeInstance* mCurBaseType;
|
||||
BfTypeReference* mCurAttributeTypeRef;
|
||||
BfFieldDef* mCurFieldDef;
|
||||
BfTypeDef* mCurTypeDef;
|
||||
BfTypeDef* mForceActiveTypeDef;
|
||||
BfTypeDef* mForceActiveTypeDef;
|
||||
ResolveKind mResolveKind;
|
||||
BfAstNode* mCurVarInitializer;
|
||||
int mArrayInitializerSize;
|
||||
|
@ -160,6 +161,7 @@ public:
|
|||
|
||||
mPopulateType = BfPopulateType_Identity;
|
||||
mCurBaseTypeRef = NULL;
|
||||
mCurBaseType = NULL;
|
||||
mCurFieldDef = NULL;
|
||||
mCurAttributeTypeRef = NULL;
|
||||
mCurTypeDef = NULL;
|
||||
|
|
|
@ -443,17 +443,7 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio
|
|||
{
|
||||
methodDef->mIsConcrete = true;
|
||||
methodDef->mIsVirtual = false;
|
||||
}
|
||||
|
||||
if (mCurTypeDef->mTypeCode == BfTypeCode_Interface)
|
||||
{
|
||||
//
|
||||
}
|
||||
else
|
||||
{
|
||||
if (methodDef->mIsConcrete)
|
||||
Fail("Only interfaces methods can be declared as 'concrete'", methodDeclaration->mVirtualSpecifier);
|
||||
}
|
||||
}
|
||||
|
||||
if (methodDef->mIsAbstract)
|
||||
{
|
||||
|
@ -1775,24 +1765,21 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
|
|||
bool doInsertNew = true;
|
||||
if (prevRevisionTypeDef != NULL)
|
||||
{
|
||||
mCurTypeDef->mIsNextRevision = true;
|
||||
mCurTypeDef->mIsNextRevision = true;
|
||||
bfParser->mTypeDefs.Add(prevRevisionTypeDef);
|
||||
|
||||
if (prevRevisionTypeDef->mDefState == BfTypeDef::DefState_AwaitingNewVersion)
|
||||
{
|
||||
delete prevRevisionTypeDef->mNextRevision;
|
||||
if (prevRevisionTypeDef->mNextRevision != NULL)
|
||||
{
|
||||
BfLogSysM("Deleting unused nextRevision %p from prevRevision %p\n", prevRevisionTypeDef->mNextRevision, prevRevisionTypeDef);
|
||||
delete prevRevisionTypeDef->mNextRevision;
|
||||
}
|
||||
prevRevisionTypeDef->mNextRevision = mCurTypeDef;
|
||||
BF_ASSERT(mCurTypeDef->mSystem != NULL);
|
||||
mCurActualTypeDef = prevRevisionTypeDef;
|
||||
doInsertNew = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (prevRevisionTypeDef->mNextRevision != NULL)
|
||||
prevRevisionTypeDef = prevRevisionTypeDef->mNextRevision;
|
||||
|
||||
prevRevisionTypeDef = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1820,8 +1807,8 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
|
|||
outerTypeDef->mNestedTypes.push_back(mCurActualTypeDef);
|
||||
}
|
||||
|
||||
BfLogSysM("Creating TypeDef %p Hash:%d from TypeDecl: %p Source: %p ResolvePass: %d AutoComplete:%d\n", mCurTypeDef, mSystem->mTypeDefs.GetHash(mCurTypeDef), typeDeclaration,
|
||||
typeDeclaration->GetSourceData(), mResolvePassData != NULL, isAutoCompleteTempType);
|
||||
BfLogSysM("Creating TypeDef %p Hash:%d from TypeDecl: %p Source: %p ResolvePass: %d AutoComplete:%d PrevRevision:%d\n", mCurTypeDef, mSystem->mTypeDefs.GetHash(mCurTypeDef), typeDeclaration,
|
||||
typeDeclaration->GetSourceData(), mResolvePassData != NULL, isAutoCompleteTempType, prevRevisionTypeDef);
|
||||
|
||||
BF_ASSERT(mCurTypeDef->mNameEx == NULL);
|
||||
|
||||
|
@ -1875,9 +1862,9 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
|
|||
|
||||
if (mCurTypeDef->mFullHash == prevRevisionTypeDef->mFullHash)
|
||||
{
|
||||
if (!mFullRefresh)
|
||||
if ((!mFullRefresh) && (!prevRevisionTypeDef->mForceUseNextRevision))
|
||||
{
|
||||
BfLogSys(bfParser->mSystem, "DefBuilder deleting typeDef with no changes %p\n", prevRevisionTypeDef);
|
||||
BfLogSys(bfParser->mSystem, "DefBuilder deleting typeDef with no changes %p prevRevision: %p\n", mCurTypeDef, prevRevisionTypeDef);
|
||||
prevRevisionTypeDef->mDefState = BfTypeDef::DefState_Defined;
|
||||
BF_ASSERT(prevRevisionTypeDef->mNextRevision == mCurTypeDef);
|
||||
prevRevisionTypeDef->mNextRevision = NULL;
|
||||
|
@ -1918,9 +1905,10 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
BfMethodDef* dynamicCastMethod = NULL;
|
||||
BfMethodDef* toStringMethod = NULL;
|
||||
bool needsEqualsMethod = ((mCurTypeDef->mTypeCode == BfTypeCode_Struct) || (mCurTypeDef->mTypeCode == BfTypeCode_Enum)) && (!mCurTypeDef->mIsStatic);
|
||||
BfMethodDef* equalsOpMethod = NULL;
|
||||
BfMethodDef* equalsMethod = NULL;
|
||||
BfMethodDef* strictEqualsMethod = NULL;
|
||||
|
||||
BfMethodDef* strictEqualsMethod = NULL;
|
||||
|
||||
bool needsStaticInit = false;
|
||||
for (int methodIdx = 0; methodIdx < (int)mCurTypeDef->mMethods.size(); methodIdx++)
|
||||
{
|
||||
|
@ -1962,7 +1950,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
|
||||
auto ctorDeclaration = (BfConstructorDeclaration*)method->mMethodDeclaration;
|
||||
if (method->mHasAppend)
|
||||
{
|
||||
{
|
||||
mCurTypeDef->mHasAppendCtor = true;
|
||||
|
||||
auto methodDef = new BfMethodDef();
|
||||
|
@ -2038,6 +2026,10 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
{
|
||||
if (method->mName == BF_METHODNAME_MARKMEMBERS_STATIC)
|
||||
_SetMethod(staticMarkMethod, method);
|
||||
if (method->mName == BF_METHODNAME_DEFAULT_EQUALS)
|
||||
_SetMethod(equalsMethod, method);
|
||||
if (method->mName == BF_METHODNAME_DEFAULT_STRICT_EQUALS)
|
||||
_SetMethod(strictEqualsMethod, method);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2061,7 +2053,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
if ((method->mParams[0]->mTypeRef->ToString() == mCurTypeDef->mName->ToString()) &&
|
||||
(method->mParams[1]->mTypeRef->ToString() == mCurTypeDef->mName->ToString()))
|
||||
{
|
||||
_SetMethod(equalsMethod, method);
|
||||
_SetMethod(equalsOpMethod, method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2300,7 +2292,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
methodDef->mAddedAfterEmit = mIsComptime;
|
||||
}
|
||||
|
||||
if ((needsEqualsMethod) && (equalsMethod == NULL))
|
||||
if ((needsEqualsMethod) && (equalsMethod == NULL) && (equalsOpMethod == NULL))
|
||||
{
|
||||
auto methodDef = new BfMethodDef();
|
||||
mCurTypeDef->mMethods.push_back(methodDef);
|
||||
|
@ -2314,7 +2306,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
methodDef->mAddedAfterEmit = mIsComptime;
|
||||
}
|
||||
|
||||
if (needsEqualsMethod)
|
||||
if ((needsEqualsMethod) && (strictEqualsMethod == NULL))
|
||||
{
|
||||
auto methodDef = new BfMethodDef();
|
||||
mCurTypeDef->mMethods.push_back(methodDef);
|
||||
|
|
|
@ -4248,6 +4248,14 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
|
|||
mModule->PopulateType(startCheckType, BfPopulateType_BaseType);
|
||||
}
|
||||
|
||||
if ((startCheckType != NULL) && (mModule->mContext->mCurTypeState != NULL))
|
||||
{
|
||||
// Don't allow lookups yet
|
||||
if ((mModule->mContext->mCurTypeState->mResolveKind == BfTypeState::ResolveKind_Attributes) &&
|
||||
(startCheckType == mModule->mContext->mCurTypeState->mTypeInstance))
|
||||
return BfTypedValue();
|
||||
}
|
||||
|
||||
String findName;
|
||||
int varSkipCount = 0;
|
||||
if (fieldName.StartsWith('@'))
|
||||
|
@ -4627,6 +4635,8 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
|
|||
|
||||
bool doAccessCheck = true;
|
||||
|
||||
if ((flags & BfLookupFieldFlag_BindOnly) != 0)
|
||||
doAccessCheck = false;
|
||||
if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mDisableObjectAccessChecksAttributeTypeDef)))
|
||||
doAccessCheck = false;
|
||||
|
||||
|
@ -4853,7 +4863,7 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
|
|||
}
|
||||
|
||||
// Check for direct auto-property access
|
||||
if (startCheckType == mModule->mCurTypeInstance)
|
||||
if ((startCheckType == mModule->mCurTypeInstance) && ((flags & BfLookupFieldFlag_BindOnly) == 0))
|
||||
{
|
||||
if (auto propertyDeclaration = BfNodeDynCast<BfPropertyDeclaration>(mPropDef->mFieldDeclaration))
|
||||
{
|
||||
|
@ -10104,19 +10114,22 @@ void BfExprEvaluator::Visit(BfTypeOfExpression* typeOfExpr)
|
|||
|
||||
bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifierNode* propName)
|
||||
{
|
||||
// We ignore errors because we go through the normal Visit(BfTypeOfExpression) if this fails, which will throw the error again
|
||||
SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
|
||||
|
||||
auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef);
|
||||
|
||||
BfType* type;
|
||||
if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeOfExpr->mTypeRef))
|
||||
//
|
||||
{
|
||||
type = mModule->ResolveTypeRefAllowUnboundGenerics(typeOfExpr->mTypeRef, BfPopulateType_Identity);
|
||||
}
|
||||
else
|
||||
{
|
||||
type = ResolveTypeRef(typeOfExpr->mTypeRef, BfPopulateType_Identity);
|
||||
// We ignore errors because we go through the normal Visit(BfTypeOfExpression) if this fails, which will throw the error again
|
||||
SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
|
||||
if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeOfExpr->mTypeRef))
|
||||
{
|
||||
SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
|
||||
type = mModule->ResolveTypeRefAllowUnboundGenerics(typeOfExpr->mTypeRef, BfPopulateType_Identity);
|
||||
}
|
||||
else
|
||||
{
|
||||
type = ResolveTypeRef(typeOfExpr->mTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_IgnoreLookupError);
|
||||
}
|
||||
}
|
||||
|
||||
if (type == NULL)
|
||||
|
@ -10206,11 +10219,42 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie
|
|||
else if ((memberName == "MinValue") || (memberName == "MaxValue"))
|
||||
{
|
||||
bool isMin = memberName == "MinValue";
|
||||
|
||||
BfType* checkType = typeInstance;
|
||||
|
||||
BfType* checkType = type;
|
||||
if (checkType->IsTypedPrimitive())
|
||||
checkType = checkType->GetUnderlyingType();
|
||||
|
||||
if (checkType->IsGenericParam())
|
||||
{
|
||||
bool foundMatch = false;
|
||||
|
||||
auto genericParamInstance = mModule->GetGenericParamInstance((BfGenericParamType*)checkType);
|
||||
if (((genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Enum) != 0) ||
|
||||
((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsInstanceOf(mModule->mCompiler->mEnumTypeDef))))
|
||||
foundMatch = true;
|
||||
|
||||
if ((mModule->mCurMethodInstance != NULL) && (mModule->mCurMethodInstance->mIsUnspecialized) && (mModule->mCurMethodInstance->mMethodInfoEx != NULL))
|
||||
{
|
||||
for (int genericParamIdx = (int)mModule->mCurMethodInstance->mMethodInfoEx->mMethodGenericArguments.size();
|
||||
genericParamIdx < mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
|
||||
{
|
||||
genericParamInstance = mModule->mCurMethodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
|
||||
if (genericParamInstance->mExternType == type)
|
||||
{
|
||||
if (((genericParamInstance->mGenericParamFlags & BfGenericParamFlag_Enum) != 0) ||
|
||||
((genericParamInstance->mTypeConstraint != NULL) && (genericParamInstance->mTypeConstraint->IsInstanceOf(mModule->mCompiler->mEnumTypeDef))))
|
||||
foundMatch = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (foundMatch)
|
||||
{
|
||||
mResult = mModule->GetDefaultTypedValue(type, false, Beefy::BfDefaultValueKind_Undef);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (checkType->IsPrimitiveType())
|
||||
{
|
||||
auto primType = (BfPrimitiveType*)checkType;
|
||||
|
@ -10257,15 +10301,15 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie
|
|||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (typeInstance->IsEnum())
|
||||
if (type->IsEnum())
|
||||
{
|
||||
mModule->Fail("'MinValue' cannot be used on enums with payloads", propName);
|
||||
mModule->Fail(StrFormat("'MinValue' cannot be used on enum with payload '%s'", mModule->TypeToString(type).c_str()), propName);
|
||||
}
|
||||
else
|
||||
{
|
||||
mModule->Fail(StrFormat("'%s' cannot be used on type '%s'", memberName.c_str(), mModule->TypeToString(typeInstance).c_str()), propName);
|
||||
mModule->Fail(StrFormat("'%s' cannot be used on type '%s'", memberName.c_str(), mModule->TypeToString(type).c_str()), propName);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -11923,17 +11967,18 @@ void BfExprEvaluator::VisitLambdaBodies(BfAstNode* body, BfFieldDtorDeclaration*
|
|||
if (auto blockBody = BfNodeDynCast<BfBlock>(body))
|
||||
mModule->VisitChild(blockBody);
|
||||
else if (auto bodyExpr = BfNodeDynCast<BfExpression>(body))
|
||||
{
|
||||
{
|
||||
auto result = mModule->CreateValueFromExpression(bodyExpr);
|
||||
if ((result) && (mModule->mCurMethodState->mClosureState != NULL) &&
|
||||
(mModule->mCurMethodState->mClosureState->mReturnTypeInferState == BfReturnTypeInferState_Inferring))
|
||||
mModule->mCurMethodState->mClosureState->mReturnType = result.mType;
|
||||
mModule->mCurMethodState->mClosureState->mReturnType = result.mType;
|
||||
}
|
||||
|
||||
while (fieldDtor != NULL)
|
||||
{
|
||||
mModule->mCurMethodState->mLeftBlockUncond = false;
|
||||
mModule->VisitChild(fieldDtor->mBody);
|
||||
fieldDtor = fieldDtor->mNextFieldDtor;
|
||||
fieldDtor = fieldDtor->mNextFieldDtor;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13829,6 +13874,9 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
|||
mModule->Fail("Too many array dimensions, consider using a jagged array.", objCreateExpr);
|
||||
}
|
||||
|
||||
if (arrayType == NULL)
|
||||
return;
|
||||
|
||||
if (isAppendAlloc)
|
||||
arrayValue = BfTypedValue(mModule->AppendAllocFromType(resultType, BfIRValue(), 0, arraySize, (int)dimLengthVals.size(), isRawArrayAlloc, zeroMemory), arrayType);
|
||||
else
|
||||
|
@ -14790,7 +14838,15 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc,
|
|||
if (unspecializedMethod == NULL)
|
||||
unspecializedMethod = mModule->GetRawMethodInstance(curTypeInst, methodDef);
|
||||
|
||||
BfType* specializedReturnType = mModule->ResolveGenericType(unspecializedMethod->mReturnType, NULL, &methodMatcher.mBestMethodGenericArguments);
|
||||
BfTypeVector* typeGenericArgs = NULL;
|
||||
auto typeUnspecMethodInstance = unspecializedMethod;
|
||||
if (curTypeInst->IsUnspecializedTypeVariation())
|
||||
{
|
||||
typeUnspecMethodInstance = mModule->GetUnspecializedMethodInstance(typeUnspecMethodInstance, true);
|
||||
typeGenericArgs = &curTypeInst->mGenericTypeInfo->mTypeGenericArguments;
|
||||
}
|
||||
|
||||
BfType* specializedReturnType = mModule->ResolveGenericType(typeUnspecMethodInstance->mReturnType, typeGenericArgs, &methodMatcher.mBestMethodGenericArguments);
|
||||
if (specializedReturnType != NULL)
|
||||
*overrideReturnType = specializedReturnType;
|
||||
}
|
||||
|
@ -18711,10 +18767,10 @@ void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr)
|
|||
int valueIdx = -1;
|
||||
for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
|
||||
{
|
||||
BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
|
||||
BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
|
||||
++valueIdx;
|
||||
if (fieldInstance->mResolvedType->IsValuelessType())
|
||||
continue;
|
||||
++valueIdx;
|
||||
auto typedVal = typedValues[valueIdx];
|
||||
if (!typedVal)
|
||||
{
|
||||
|
@ -20399,11 +20455,70 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
BfType* wantType = leftValue.mType;
|
||||
if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
|
||||
wantType = NULL; // Don't presume
|
||||
wantType = mModule->FixIntUnknown(wantType);
|
||||
|
||||
if ((binaryOp == BfBinaryOp_NullCoalesce) && (leftValue) && ((leftValue.mType->IsPointer()) || (leftValue.mType->IsFunction()) || (leftValue.mType->IsObject())))
|
||||
{
|
||||
auto prevBB = mModule->mBfIRBuilder->GetInsertBlock();
|
||||
|
||||
auto rhsBB = mModule->mBfIRBuilder->CreateBlock("nullc.rhs");
|
||||
auto endBB = mModule->mBfIRBuilder->CreateBlock("nullc.end");
|
||||
|
||||
BfIRValue isNull;
|
||||
if (leftValue.mType->IsFunction())
|
||||
isNull = mModule->mBfIRBuilder->CreateIsNull(
|
||||
mModule->mBfIRBuilder->CreateIntToPtr(leftValue.mValue, mModule->mBfIRBuilder->MapType(mModule->GetPrimitiveType(BfTypeCode_NullPtr))));
|
||||
else
|
||||
isNull = mModule->mBfIRBuilder->CreateIsNull(leftValue.mValue);
|
||||
mModule->mBfIRBuilder->CreateCondBr(isNull, rhsBB, endBB);
|
||||
|
||||
mModule->AddBasicBlock(rhsBB);
|
||||
rightValue = mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast));
|
||||
if (!rightValue)
|
||||
{
|
||||
mModule->AssertErrorState();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto rightToLeftValue = mModule->CastToValue(rightExpression, rightValue, leftValue.mType, BfCastFlags_SilentFail);
|
||||
if (rightToLeftValue)
|
||||
{
|
||||
rightValue = BfTypedValue(rightToLeftValue, leftValue.mType);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto leftToRightValue = mModule->CastToValue(leftExpression, leftValue, rightValue.mType, BfCastFlags_SilentFail);
|
||||
if (leftToRightValue)
|
||||
{
|
||||
leftValue = BfTypedValue(leftToRightValue, rightValue.mType);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Note: Annoying trigraph split for '??'
|
||||
mModule->Fail(StrFormat("Operator '?" "?' cannot be applied to operands of type '%s' and '%s'",
|
||||
mModule->TypeToString(leftValue.mType).c_str(), mModule->TypeToString(rightValue.mType).c_str()), opToken);
|
||||
leftValue = mModule->GetDefaultTypedValue(rightValue.mType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mModule->mBfIRBuilder->CreateBr(endBB);
|
||||
|
||||
auto endRhsBB = mModule->mBfIRBuilder->GetInsertBlock();
|
||||
mModule->AddBasicBlock(endBB);
|
||||
auto phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(leftValue.mType), 2);
|
||||
mModule->mBfIRBuilder->AddPhiIncoming(phi, leftValue.mValue, prevBB);
|
||||
mModule->mBfIRBuilder->AddPhiIncoming(phi, rightValue.mValue, endRhsBB);
|
||||
mResult = BfTypedValue(phi, leftValue.mType);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
rightValue = mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast));
|
||||
if ((!leftValue) || (!rightValue))
|
||||
return;
|
||||
|
@ -20611,58 +20726,6 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
|||
return;
|
||||
}
|
||||
|
||||
if ((binaryOp == BfBinaryOp_NullCoalesce) && ((leftValue.mType->IsPointer()) || (leftValue.mType->IsObject())))
|
||||
{
|
||||
auto prevBB = mModule->mBfIRBuilder->GetInsertBlock();
|
||||
|
||||
auto rhsBB = mModule->mBfIRBuilder->CreateBlock("nullc.rhs");
|
||||
auto endBB = mModule->mBfIRBuilder->CreateBlock("nullc.end");
|
||||
|
||||
auto isNull = mModule->mBfIRBuilder->CreateIsNull(leftValue.mValue);
|
||||
mModule->mBfIRBuilder->CreateCondBr(isNull, rhsBB, endBB);
|
||||
|
||||
mModule->AddBasicBlock(rhsBB);
|
||||
if (!rightValue)
|
||||
{
|
||||
mModule->AssertErrorState();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto rightToLeftValue = mModule->CastToValue(rightExpression, rightValue, leftValue.mType, BfCastFlags_SilentFail);
|
||||
if (rightToLeftValue)
|
||||
{
|
||||
rightValue = BfTypedValue(rightToLeftValue, leftValue.mType);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto leftToRightValue = mModule->CastToValue(leftExpression, leftValue, rightValue.mType, BfCastFlags_SilentFail);
|
||||
if (leftToRightValue)
|
||||
{
|
||||
leftValue = BfTypedValue(leftToRightValue, rightValue.mType);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Note: Annoying trigraph split for '??'
|
||||
mModule->Fail(StrFormat("Operator '?" "?' cannot be applied to operands of type '%s' and '%s'",
|
||||
mModule->TypeToString(leftValue.mType).c_str(), mModule->TypeToString(rightValue.mType).c_str()), opToken);
|
||||
leftValue = mModule->GetDefaultTypedValue(rightValue.mType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mModule->mBfIRBuilder->CreateBr(endBB);
|
||||
|
||||
auto endRhsBB = mModule->mBfIRBuilder->GetInsertBlock();
|
||||
mModule->AddBasicBlock(endBB);
|
||||
auto phi = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(leftValue.mType), 2);
|
||||
mModule->mBfIRBuilder->AddPhiIncoming(phi, leftValue.mValue, prevBB);
|
||||
mModule->mBfIRBuilder->AddPhiIncoming(phi, rightValue.mValue, endRhsBB);
|
||||
mResult = BfTypedValue(phi, leftValue.mType);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
|
||||
{
|
||||
forceLeftType = true;
|
||||
|
|
|
@ -615,17 +615,7 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f
|
|||
else if (fromConst->mConstType == BfConstType_GlobalVar)
|
||||
{
|
||||
auto fromGlobalVar = (BfGlobalVar*)fromConst;
|
||||
auto constGV = mTempAlloc.Alloc<BfGlobalVar>();
|
||||
chunkId = mTempAlloc.GetChunkedId(constGV);
|
||||
constGV->mStreamId = -1;
|
||||
constGV->mConstType = BfConstType_GlobalVar;
|
||||
constGV->mType = fromGlobalVar->mType;
|
||||
constGV->mIsConst = fromGlobalVar->mIsConst;
|
||||
constGV->mLinkageType = fromGlobalVar->mLinkageType;
|
||||
constGV->mInitializer = fromGlobalVar->mInitializer;
|
||||
constGV->mName = AllocStr(fromGlobalVar->mName);
|
||||
constGV->mIsTLS = fromGlobalVar->mIsTLS;
|
||||
copiedConst = (BfConstant*)constGV;
|
||||
return CreateGlobalVariableConstant(fromGlobalVar->mType, fromGlobalVar->mIsConst, fromGlobalVar->mLinkageType, fromGlobalVar->mInitializer, fromGlobalVar->mName, fromGlobalVar->mIsTLS);
|
||||
}
|
||||
else if (fromConst->mConstType == BfConstType_GEP32_2)
|
||||
{
|
||||
|
@ -1875,6 +1865,7 @@ void BfIRBuilder::ClearConstData()
|
|||
mTempAlloc.Clear();
|
||||
mConstMemMap.Clear();
|
||||
mFunctionMap.Clear();
|
||||
mGlobalVarMap.Clear();
|
||||
BF_ASSERT(mMethodTypeMap.GetCount() == 0);
|
||||
BF_ASSERT(mTypeMap.GetCount() == 0);
|
||||
BF_ASSERT(mDITemporaryTypes.size() == 0);
|
||||
|
@ -1889,6 +1880,7 @@ void BfIRBuilder::ClearNonConstData()
|
|||
{
|
||||
mMethodTypeMap.Clear();
|
||||
mFunctionMap.Clear();
|
||||
mGlobalVarMap.Clear();
|
||||
mTypeMap.Clear();
|
||||
mConstMemMap.Clear();
|
||||
mDITemporaryTypes.Clear();
|
||||
|
@ -2996,11 +2988,6 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
|
|||
|
||||
if (fieldInstance->mConstIdx != -1)
|
||||
{
|
||||
if (fieldInstance->GetFieldDef()->mName == "mMembers")
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
||||
constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
|
||||
staticValue = mModule->ConstantToCurrent(constant, typeInstance->mConstHolder, resolvedFieldType);
|
||||
}
|
||||
|
@ -4743,39 +4730,53 @@ BfIRValue BfIRBuilder::CreateStackRestore(BfIRValue stackVal)
|
|||
return retVal;
|
||||
}
|
||||
|
||||
BfIRValue BfIRBuilder::CreateGlobalVariable(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS)
|
||||
void BfIRBuilder::CreateGlobalVariable(BfIRValue irValue)
|
||||
{
|
||||
auto globalVar = (BfGlobalVar*)GetConstant(irValue);
|
||||
|
||||
if ((!mIgnoreWrites) && (globalVar->mStreamId == -1))
|
||||
{
|
||||
if (globalVar->mInitializer)
|
||||
mHasGlobalDefs = true;
|
||||
|
||||
BfIRValue retVal = WriteCmd(BfIRCmd_GlobalVariable, globalVar->mType, globalVar->mIsConst, (uint8)globalVar->mLinkageType, String(globalVar->mName), globalVar->mIsTLS, globalVar->mInitializer);
|
||||
globalVar->mStreamId = retVal.mId;
|
||||
|
||||
NEW_CMD_INSERTED_IRVALUE;
|
||||
}
|
||||
}
|
||||
|
||||
BfIRValue BfIRConstHolder::CreateGlobalVariableConstant(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS)
|
||||
{
|
||||
BfIRValue* valuePtr = NULL;
|
||||
if ((!mGlobalVarMap.TryAdd(name, NULL, &valuePtr)) && (!initializer))
|
||||
{
|
||||
return *valuePtr;
|
||||
}
|
||||
|
||||
BF_ASSERT(varType);
|
||||
|
||||
auto constGV = mTempAlloc.Alloc<BfGlobalVar>();
|
||||
int chunkId = mTempAlloc.GetChunkedId(constGV);
|
||||
constGV->mStreamId = -1;
|
||||
constGV->mConstType = BfConstType_GlobalVar;
|
||||
constGV->mType = varType;
|
||||
constGV->mConstType = BfConstType_GlobalVar;
|
||||
constGV->mType = varType;
|
||||
constGV->mIsConst = isConstant;
|
||||
constGV->mLinkageType = linkageType;
|
||||
constGV->mInitializer = initializer;
|
||||
constGV->mName = AllocStr(name);
|
||||
constGV->mIsTLS = isTLS;
|
||||
constGV->mIsTLS = isTLS;
|
||||
|
||||
if (!mIgnoreWrites)
|
||||
{
|
||||
if (initializer)
|
||||
mHasGlobalDefs = true;
|
||||
auto irValue = BfIRValue(BfIRValueFlags_Const, chunkId);;
|
||||
*valuePtr = irValue;
|
||||
return irValue;
|
||||
}
|
||||
|
||||
BfIRValue retVal = WriteCmd(BfIRCmd_GlobalVariable, varType, isConstant, (uint8)linkageType, name, isTLS, initializer);
|
||||
constGV->mStreamId = retVal.mId;
|
||||
retVal.mFlags = BfIRValueFlags_Const;
|
||||
#ifdef CHECK_CONSTHOLDER
|
||||
retVal.mHolder = this;
|
||||
#endif
|
||||
retVal.mId = chunkId;
|
||||
NEW_CMD_INSERTED_IRVALUE;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
auto irValue = BfIRValue(BfIRValueFlags_Const, chunkId);
|
||||
return irValue;
|
||||
BfIRValue BfIRBuilder::CreateGlobalVariable(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS)
|
||||
{
|
||||
auto irValue = CreateGlobalVariableConstant(varType, isConstant, linkageType, initializer, name, isTLS);
|
||||
CreateGlobalVariable(irValue);
|
||||
return irValue;
|
||||
}
|
||||
|
||||
void BfIRBuilder::GlobalVar_SetUnnamedAddr(BfIRValue val, bool unnamedAddr)
|
||||
|
|
|
@ -901,6 +901,7 @@ class BfIRConstHolder
|
|||
public:
|
||||
BumpAllocatorT<256> mTempAlloc;
|
||||
BfModule* mModule;
|
||||
Dictionary<String, BfIRValue> mGlobalVarMap;
|
||||
|
||||
public:
|
||||
void FixTypeCode(BfTypeCode& typeCode);
|
||||
|
@ -936,6 +937,7 @@ public:
|
|||
BfIRValue CreateTypeOf(BfType* type);
|
||||
BfIRValue CreateTypeOf(BfType* type, BfIRValue typeData);
|
||||
BfIRValue GetUndefConstValue(BfIRType type);
|
||||
BfIRValue CreateGlobalVariableConstant(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS = false);
|
||||
|
||||
bool WriteConstant(BfIRValue val, void* ptr, BfType* type);
|
||||
BfIRValue ReadConstant(void* ptr, BfType* type);
|
||||
|
@ -979,7 +981,7 @@ public:
|
|||
bool mHasDebugInfo;
|
||||
bool mHasDebugLineInfo;
|
||||
Dictionary<BfMethodRef, BfIRFunctionType> mMethodTypeMap;
|
||||
Dictionary<String, BfIRFunction> mFunctionMap;
|
||||
Dictionary<String, BfIRFunction> mFunctionMap;
|
||||
Dictionary<BfType*, BfIRPopulateType> mTypeMap;
|
||||
Dictionary<int, BfIRValue> mConstMemMap;
|
||||
Array<BfTypeInstance*> mDITemporaryTypes;
|
||||
|
@ -1227,6 +1229,7 @@ public:
|
|||
BfIRValue CreateStackRestore(BfIRValue stackVal);
|
||||
|
||||
BfIRValue CreateGlobalVariable(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS = false);
|
||||
void CreateGlobalVariable(BfIRValue irValue);
|
||||
void GlobalVar_SetUnnamedAddr(BfIRValue val, bool unnamedAddr);
|
||||
void GlobalVar_SetInitializer(BfIRValue globalVar, BfIRValue initVal);
|
||||
void GlobalVar_SetAlignment(BfIRValue globalVar, int alignment);
|
||||
|
|
|
@ -810,13 +810,17 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry,
|
|||
llvm::GlobalVariable* globalVariable = mLLVMModule->getGlobalVariable(name.c_str(), true);
|
||||
if (globalVariable == NULL)
|
||||
{
|
||||
globalVariable = new llvm::GlobalVariable(
|
||||
*mLLVMModule,
|
||||
varType,
|
||||
isConstant,
|
||||
LLVMMapLinkageType(linkageType),
|
||||
initializer,
|
||||
name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal);
|
||||
globalVariable = mLLVMModule->getGlobalVariable(name.c_str());
|
||||
if (globalVariable == NULL)
|
||||
{
|
||||
globalVariable = new llvm::GlobalVariable(
|
||||
*mLLVMModule,
|
||||
varType,
|
||||
isConstant,
|
||||
LLVMMapLinkageType(linkageType),
|
||||
initializer,
|
||||
name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal);
|
||||
}
|
||||
}
|
||||
llvmValue = globalVariable;
|
||||
|
||||
|
@ -2389,13 +2393,17 @@ void BfIRCodeGen::HandleNextCmd()
|
|||
CMD_PARAM(bool, isTLS);
|
||||
CMD_PARAM(llvm::Constant*, initializer);
|
||||
|
||||
auto globalVariable = new llvm::GlobalVariable(
|
||||
*mLLVMModule,
|
||||
varType,
|
||||
isConstant,
|
||||
LLVMMapLinkageType(linkageType),
|
||||
initializer,
|
||||
name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal);
|
||||
auto globalVariable = mLLVMModule->getGlobalVariable(name.c_str());
|
||||
if (globalVariable == NULL)
|
||||
{
|
||||
globalVariable = new llvm::GlobalVariable(
|
||||
*mLLVMModule,
|
||||
varType,
|
||||
isConstant,
|
||||
LLVMMapLinkageType(linkageType),
|
||||
initializer,
|
||||
name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal);
|
||||
}
|
||||
SetResult(curId, globalVariable);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -1222,7 +1222,10 @@ void BfModule::StartNewRevision(RebuildKind rebuildKind, bool force)
|
|||
|
||||
// Clear this here, not in ClearModuleData, so we preserve those references even after writing out module
|
||||
if (rebuildKind != BfModule::RebuildKind_None) // Leave string pool refs for when we need to use things like [LinkName("")] methods bofore re-reification
|
||||
mStringPoolRefs.Clear();
|
||||
{
|
||||
mStringPoolRefs.Clear();
|
||||
mUnreifiedStringPoolRefs.Clear();
|
||||
}
|
||||
mDllImportEntries.Clear();
|
||||
mImportFileNames.Clear();
|
||||
for (auto& pairVal : mDeferredMethodCallData)
|
||||
|
@ -1543,7 +1546,7 @@ BfIRValue BfModule::CreateStringCharPtr(const StringImpl& str, int stringId, boo
|
|||
}
|
||||
|
||||
BfIRValue BfModule::CreateStringObjectValue(const StringImpl& str, int stringId, bool define)
|
||||
{
|
||||
{
|
||||
auto stringTypeInst = ResolveTypeDef(mCompiler->mStringTypeDef, define ? BfPopulateType_Data : BfPopulateType_Declaration)->ToTypeInstance();
|
||||
mBfIRBuilder->PopulateType(stringTypeInst);
|
||||
|
||||
|
@ -1654,8 +1657,14 @@ String* BfModule::GetStringPoolString(BfIRValue constantStr, BfIRConstHolder * c
|
|||
return NULL;
|
||||
}
|
||||
|
||||
BfIRValue BfModule::GetStringCharPtr(int stringId)
|
||||
BfIRValue BfModule::GetStringCharPtr(int stringId, bool force)
|
||||
{
|
||||
if ((mBfIRBuilder->mIgnoreWrites) && (!force))
|
||||
{
|
||||
mUnreifiedStringPoolRefs.Add(stringId);
|
||||
return mBfIRBuilder->CreateConst(BfTypeCode_StringId, stringId);
|
||||
}
|
||||
|
||||
BfIRValue* irValue = NULL;
|
||||
if (!mStringCharPtrPool.TryAdd(stringId, NULL, &irValue))
|
||||
return *irValue;
|
||||
|
@ -1670,13 +1679,13 @@ BfIRValue BfModule::GetStringCharPtr(int stringId)
|
|||
return strCharPtrConst;
|
||||
}
|
||||
|
||||
BfIRValue BfModule::GetStringCharPtr(BfIRValue strValue)
|
||||
BfIRValue BfModule::GetStringCharPtr(BfIRValue strValue, bool force)
|
||||
{
|
||||
if (strValue.IsConst())
|
||||
{
|
||||
int stringId = GetStringPoolIdx(strValue);
|
||||
BF_ASSERT(stringId != -1);
|
||||
return GetStringCharPtr(stringId);
|
||||
return GetStringCharPtr(stringId, force);
|
||||
}
|
||||
|
||||
BfIRValue charPtrPtr = mBfIRBuilder->CreateInBoundsGEP(strValue, 0, 1);
|
||||
|
@ -1684,27 +1693,33 @@ BfIRValue BfModule::GetStringCharPtr(BfIRValue strValue)
|
|||
return charPtr;
|
||||
}
|
||||
|
||||
BfIRValue BfModule::GetStringCharPtr(const StringImpl& str)
|
||||
BfIRValue BfModule::GetStringCharPtr(const StringImpl& str, bool force)
|
||||
{
|
||||
return GetStringCharPtr(GetStringObjectValue(str));
|
||||
return GetStringCharPtr(GetStringObjectValue(str, force), force);
|
||||
}
|
||||
|
||||
BfIRValue BfModule::GetStringObjectValue(int strId)
|
||||
BfIRValue BfModule::GetStringObjectValue(int strId, bool define, bool force)
|
||||
{
|
||||
BfIRValue* objValue;
|
||||
if (mStringObjectPool.TryGetValue(strId, &objValue))
|
||||
return *objValue;
|
||||
|
||||
auto stringPoolEntry = mContext->mStringObjectIdMap[strId];
|
||||
return GetStringObjectValue(stringPoolEntry.mString, true);
|
||||
return GetStringObjectValue(stringPoolEntry.mString, define, force);
|
||||
}
|
||||
|
||||
BfIRValue BfModule::GetStringObjectValue(const StringImpl& str, bool define)
|
||||
BfIRValue BfModule::GetStringObjectValue(const StringImpl& str, bool define, bool force)
|
||||
{
|
||||
auto stringType = ResolveTypeDef(mCompiler->mStringTypeDef, define ? BfPopulateType_Data : BfPopulateType_Declaration);
|
||||
mBfIRBuilder->PopulateType(stringType);
|
||||
|
||||
int strId = mContext->GetStringLiteralId(str);
|
||||
int strId = mContext->GetStringLiteralId(str);
|
||||
|
||||
if ((mBfIRBuilder->mIgnoreWrites) && (!force))
|
||||
{
|
||||
mUnreifiedStringPoolRefs.Add(strId);
|
||||
return mBfIRBuilder->CreateConst(BfTypeCode_StringId, strId);
|
||||
}
|
||||
|
||||
BfIRValue* irValuePtr = NULL;
|
||||
if (!mStringObjectPool.TryAdd(strId, NULL, &irValuePtr))
|
||||
|
@ -1916,13 +1931,7 @@ void BfModule::AddStackAlloc(BfTypedValue val, BfIRValue arraySize, BfAstNode* r
|
|||
bool hadDtorCall = false;
|
||||
while (checkBaseType != NULL)
|
||||
{
|
||||
checkBaseType->mTypeDef->PopulateMemberSets();
|
||||
BfMemberSetEntry* entry = NULL;
|
||||
BfMethodDef* dtorMethodDef = NULL;
|
||||
checkBaseType->mTypeDef->mMethodSet.TryGetWith(String("~this"), &entry);
|
||||
if (entry != NULL)
|
||||
dtorMethodDef = (BfMethodDef*)entry->mMemberDef;
|
||||
|
||||
BfMethodDef* dtorMethodDef = checkBaseType->mTypeDef->GetMethodByName("~this");
|
||||
if (dtorMethodDef != NULL)
|
||||
{
|
||||
auto dtorMethodInstance = GetMethodInstance(checkBaseType, dtorMethodDef, BfTypeVector());
|
||||
|
@ -3416,10 +3425,11 @@ void BfModule::AddDependency(BfType* usedType, BfType* userType, BfDependencyMap
|
|||
BfModule* usedModule;
|
||||
if (usedType->IsFunction())
|
||||
{
|
||||
auto typeInst = usedType->ToTypeInstance();
|
||||
if (typeInst->mBaseType == NULL)
|
||||
PopulateType(typeInst);
|
||||
usedModule = typeInst->mBaseType->GetModule();
|
||||
if (mCompiler->mFunctionTypeDef != NULL)
|
||||
{
|
||||
auto functionType = ResolveTypeDef(mCompiler->mFunctionTypeDef)->ToTypeInstance();
|
||||
usedModule = functionType->GetModule();
|
||||
}
|
||||
}
|
||||
else
|
||||
usedModule = usedType->GetModule();
|
||||
|
@ -5235,7 +5245,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
typeFlags |= BfTypeFlags_Delegate;
|
||||
if (type->IsFunction())
|
||||
typeFlags |= BfTypeFlags_Function;
|
||||
if (type->WantsGCMarking())
|
||||
if ((type->mDefineState != BfTypeDefineState_CETypeInit) && (type->WantsGCMarking()))
|
||||
typeFlags |= BfTypeFlags_WantsMarking;
|
||||
|
||||
int virtSlotIdx = -1;
|
||||
|
@ -5906,8 +5916,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
|
||||
if (needsTypeNames)
|
||||
{
|
||||
typeNameConst = GetStringObjectValue(typeDef->mName->mString, true);
|
||||
namespaceConst = GetStringObjectValue(typeDef->mNamespace.ToString(), true);
|
||||
typeNameConst = GetStringObjectValue(typeDef->mName->mString, !mIsComptimeModule);
|
||||
namespaceConst = GetStringObjectValue(typeDef->mNamespace.ToString(), !mIsComptimeModule);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5967,7 +5977,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
// Fields
|
||||
BfType* reflectFieldDataType = ResolveTypeDef(mCompiler->mReflectFieldDataDef);
|
||||
BfIRValue emptyValueType = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(reflectFieldDataType->ToTypeInstance()->mBaseType), SizedArray<BfIRValue, 1>());
|
||||
|
||||
|
||||
auto _HandleCustomAttrs = [&](BfCustomAttributes* customAttributes)
|
||||
{
|
||||
if (customAttributes == NULL)
|
||||
|
@ -6023,7 +6033,28 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
PUSH_INT16(0); // mSize
|
||||
|
||||
PUSH_INT32(attr->mType->mTypeId); // mType
|
||||
PUSH_INT16(attr->mCtor->mIdx);
|
||||
|
||||
int ctorIdx = -1;
|
||||
int ctorCount = 0;
|
||||
|
||||
attr->mType->mTypeDef->PopulateMemberSets();
|
||||
BfMemberSetEntry* entry;
|
||||
if (attr->mType->mTypeDef->mMethodSet.TryGetWith(String("__BfCtor"), &entry))
|
||||
{
|
||||
BfMethodDef* nextMethodDef = (BfMethodDef*)entry->mMemberDef;
|
||||
while (nextMethodDef != NULL)
|
||||
{
|
||||
if (nextMethodDef == attr->mCtor)
|
||||
ctorIdx = ctorCount;
|
||||
nextMethodDef = nextMethodDef->mNextWithSameName;
|
||||
ctorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
BF_ASSERT(ctorIdx != -1);
|
||||
if (ctorIdx != -1)
|
||||
ctorIdx = (ctorCount - 1) - ctorIdx;
|
||||
PUSH_INT16(ctorIdx);
|
||||
|
||||
auto ctorMethodInstance = GetRawMethodInstanceAtIdx(attr->mType, attr->mCtor->mIdx);
|
||||
int argIdx = 0;
|
||||
|
@ -6047,7 +6078,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
*orderedIdPtr = (int)usedStringIdMap.size() - 1;
|
||||
}
|
||||
|
||||
GetStringObjectValue(stringId);
|
||||
GetStringObjectValue(stringId, true, true);
|
||||
PUSH_INT8(0xFF); // String
|
||||
PUSH_INT32(*orderedIdPtr);
|
||||
argIdx++;
|
||||
|
@ -6067,7 +6098,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
*orderedIdPtr = (int)usedStringIdMap.size() - 1;
|
||||
}
|
||||
|
||||
GetStringObjectValue(stringId);
|
||||
GetStringObjectValue(stringId, true, true);
|
||||
PUSH_INT8(0xFF); // String
|
||||
PUSH_INT32(*orderedIdPtr);
|
||||
argIdx++;
|
||||
|
@ -6231,7 +6262,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
BfType* payloadType = typeInstance->GetUnionInnerType();
|
||||
if (!payloadType->IsValuelessType())
|
||||
{
|
||||
BfIRValue payloadNameConst = GetStringObjectValue("$payload", true);
|
||||
BfIRValue payloadNameConst = GetStringObjectValue("$payload", !mIsComptimeModule);
|
||||
SizedArray<BfIRValue, 8> payloadFieldVals =
|
||||
{
|
||||
emptyValueType,
|
||||
|
@ -6246,7 +6277,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
}
|
||||
|
||||
BfType* dscrType = typeInstance->GetDiscriminatorType();
|
||||
BfIRValue dscrNameConst = GetStringObjectValue("$discriminator", true);
|
||||
BfIRValue dscrNameConst = GetStringObjectValue("$discriminator", !mIsComptimeModule);
|
||||
SizedArray<BfIRValue, 8> dscrFieldVals =
|
||||
{
|
||||
emptyValueType,
|
||||
|
@ -6268,7 +6299,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
BfFieldInstance* fieldInstance = &typeInstance->mFieldInstances[fieldIdx];
|
||||
BfFieldDef* fieldDef = fieldInstance->GetFieldDef();
|
||||
|
||||
BfIRValue fieldNameConst = GetStringObjectValue(fieldDef->mName, true);
|
||||
BfIRValue fieldNameConst = GetStringObjectValue(fieldDef->mName, !mIsComptimeModule);
|
||||
|
||||
int typeId = 0;
|
||||
auto fieldType = fieldInstance->GetResolvedType();
|
||||
|
@ -6448,6 +6479,14 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
BfType* reflectParamDataType = ResolveTypeDef(mCompiler->mReflectParamDataDef);
|
||||
BfType* reflectParamDataPtrType = CreatePointerType(reflectParamDataType);
|
||||
|
||||
struct _SortedMethodInfo
|
||||
{
|
||||
BfMethodDef* mMethodDef;
|
||||
BfCustomAttributes* mMethodCustomAttributes;
|
||||
};
|
||||
|
||||
Array<_SortedMethodInfo> sortedMethodList;
|
||||
|
||||
SizedArray<BfIRValue, 16> methodTypes;
|
||||
for (int methodIdx = 0; methodIdx < (int)typeDef->mMethods.size(); methodIdx++)
|
||||
{
|
||||
|
@ -6460,7 +6499,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
|
||||
auto methodInstanceGroup = &typeInstance->mMethodInstanceGroups[methodIdx];
|
||||
if (!methodInstanceGroup->IsImplemented())
|
||||
continue;
|
||||
continue;
|
||||
auto methodDef = typeDef->mMethods[methodIdx];
|
||||
if (methodDef->mIsNoReflect)
|
||||
continue;
|
||||
|
@ -6474,12 +6513,12 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
continue;
|
||||
if (!defaultMethod->mIsReified)
|
||||
continue;
|
||||
|
||||
|
||||
if ((defaultMethod->mChainType == BfMethodChainType_ChainMember) || (defaultMethod->mChainType == BfMethodChainType_ChainSkip))
|
||||
continue;
|
||||
if (defaultMethod->mMethodDef->mMethodType == BfMethodType_CtorNoBody)
|
||||
continue;
|
||||
|
||||
continue;
|
||||
|
||||
auto methodReflectKind = (BfReflectKind)(reflectKind & ~BfReflectKind_User);
|
||||
|
||||
bool includeMethod = reflectIncludeAllMethods;
|
||||
|
@ -6501,10 +6540,10 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((!mIsComptimeModule) && (!typeInstance->IsTypeMemberAccessible(methodDef->mDeclaringType, mProject)))
|
||||
continue;
|
||||
|
||||
|
||||
//
|
||||
{
|
||||
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeInstance);
|
||||
|
@ -6522,13 +6561,42 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
includeMethod = true;
|
||||
if ((methodDef->mIsStatic) && ((methodReflectKind & BfReflectKind_StaticMethods) != 0))
|
||||
includeMethod = true;
|
||||
|
||||
|
||||
if ((!includeMethod) && (typeOptions != NULL))
|
||||
includeMethod = ApplyTypeOptionMethodFilters(includeMethod, methodDef, typeOptions);
|
||||
|
||||
|
||||
if (!includeMethod)
|
||||
continue;
|
||||
|
||||
sortedMethodList.Add({ methodDef, methodCustomAttributes });
|
||||
}
|
||||
|
||||
auto _GetMethodKind = [](BfMethodDef* methodDef)
|
||||
{
|
||||
if (methodDef->mMethodType == BfMethodType_Ctor)
|
||||
return 0;
|
||||
return 1;
|
||||
};
|
||||
|
||||
std::sort(sortedMethodList.begin(), sortedMethodList.end(), [_GetMethodKind](const _SortedMethodInfo& lhs, const _SortedMethodInfo& rhs)
|
||||
{
|
||||
int lhsKind = _GetMethodKind(lhs.mMethodDef);
|
||||
int rhsKind = _GetMethodKind(rhs.mMethodDef);
|
||||
|
||||
if (lhsKind != rhsKind)
|
||||
return lhsKind < rhsKind;
|
||||
if (lhs.mMethodDef->mName != rhs.mMethodDef->mName)
|
||||
return lhs.mMethodDef->mName < rhs.mMethodDef->mName;
|
||||
return lhs.mMethodDef->mIdx < rhs.mMethodDef->mIdx;
|
||||
});
|
||||
|
||||
for (auto& methodInfo : sortedMethodList)
|
||||
{
|
||||
auto methodDef = methodInfo.mMethodDef;
|
||||
int methodIdx = methodDef->mIdx;
|
||||
auto methodInstanceGroup = &typeInstance->mMethodInstanceGroups[methodIdx];
|
||||
auto defaultMethod = methodInstanceGroup->mDefault;
|
||||
|
||||
BfModuleMethodInstance moduleMethodInstance;
|
||||
BfIRValue funcVal = voidPtrNull;
|
||||
|
||||
|
@ -6544,11 +6612,11 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
funcVal = mBfIRBuilder->CreateBitCast(moduleMethodInstance.mFunc, voidPtrIRType);
|
||||
}
|
||||
|
||||
BfIRValue methodNameConst = GetStringObjectValue(methodDef->mName, true);
|
||||
BfIRValue methodNameConst = GetStringObjectValue(methodDef->mName, !mIsComptimeModule);
|
||||
|
||||
BfMethodFlags methodFlags = defaultMethod->GetMethodFlags();
|
||||
|
||||
int customAttrIdx = _HandleCustomAttrs(methodCustomAttributes);
|
||||
int customAttrIdx = _HandleCustomAttrs(methodInfo.mMethodCustomAttributes);
|
||||
|
||||
enum ParamFlags
|
||||
{
|
||||
|
@ -6567,7 +6635,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
|||
if (defaultMethod->GetParamIsSplat(paramIdx))
|
||||
paramFlags = (ParamFlags)(paramFlags | ParamFlag_Splat);
|
||||
|
||||
BfIRValue paramNameConst = GetStringObjectValue(paramName, true);
|
||||
BfIRValue paramNameConst = GetStringObjectValue(paramName, !mIsComptimeModule);
|
||||
|
||||
SizedArray<BfIRValue, 8> paramDataVals =
|
||||
{
|
||||
|
@ -7150,7 +7218,7 @@ BfIRFunction BfModule::GetBuiltInFunc(BfBuiltInFuncType funcTypeId)
|
|||
return mBuiltInFuncs[(int)funcTypeId];
|
||||
}
|
||||
|
||||
void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericParamInstance, bool isUnspecialized)
|
||||
void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericParamInstance, bool isUnspecialized, Array<BfTypeReference*>* deferredResolveTypes)
|
||||
{
|
||||
BfGenericParamDef* genericParamDef = genericParamInstance->GetGenericParamDef();
|
||||
BfExternalConstraintDef* externConstraintDef = genericParamInstance->GetExternConstraintDef();
|
||||
|
@ -7256,14 +7324,23 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar
|
|||
if (bfAutocomplete != NULL)
|
||||
bfAutocomplete->CheckTypeRef(constraintTypeRef, true);
|
||||
//TODO: Constraints may refer to other generic params (of either type or method)
|
||||
// TO allow resolution, perhaps move this generic param initalization into GetMethodInstance (passing a genericPass bool)
|
||||
// TO allow resolution, perhaps move this generic param initialization into GetMethodInstance (passing a genericPass bool)
|
||||
|
||||
BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_AllowGenericMethodParamConstValue;
|
||||
if (isUnspecialized)
|
||||
resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_DisallowComptime);
|
||||
auto constraintType = ResolveTypeRef(constraintTypeRef, BfPopulateType_Declaration, resolveFlags);
|
||||
// We we have a deferredResolveTypes then we defer the generic validation, because we may have a case like
|
||||
// `where T : Dictionay<TElem, int> and TElem : IHashable` and we don't want to throw the error on `T` before we build `TElem`
|
||||
auto constraintType = ResolveTypeRef(constraintTypeRef, (deferredResolveTypes != NULL) ? BfPopulateType_Identity : BfPopulateType_Declaration, resolveFlags);
|
||||
if (constraintType != NULL)
|
||||
{
|
||||
{
|
||||
if (deferredResolveTypes != NULL)
|
||||
{
|
||||
PopulateType(constraintType, BfPopulateType_Declaration);
|
||||
if (constraintType->IsUnspecializedTypeVariation())
|
||||
deferredResolveTypes->Add(constraintTypeRef);
|
||||
}
|
||||
|
||||
if ((constraintDef->mGenericParamFlags & BfGenericParamFlag_Const) != 0)
|
||||
{
|
||||
bool isValidTypeCode = false;
|
||||
|
@ -7444,11 +7521,11 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
|||
origCheckArgType = origCheckArgType->GetUnderlyingType();
|
||||
|
||||
bool argMayBeReferenceType = false;
|
||||
|
||||
|
||||
int checkGenericParamFlags = 0;
|
||||
if (checkArgType->IsGenericParam())
|
||||
{
|
||||
auto checkGenericParamInst = GetGenericParamInstance((BfGenericParamType*)checkArgType);
|
||||
BfGenericParamInstance* checkGenericParamInst = GetGenericParamInstance((BfGenericParamType*)checkArgType);
|
||||
checkGenericParamFlags = checkGenericParamInst->mGenericParamFlags;
|
||||
if (checkGenericParamInst->mTypeConstraint != NULL)
|
||||
checkArgType = checkGenericParamInst->mTypeConstraint;
|
||||
|
@ -7782,7 +7859,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
|
|||
if (TypeIsSubTypeOf(wrappedStructType, typeConstraintInst))
|
||||
implementsInterface = true;
|
||||
}
|
||||
|
||||
|
||||
if (!implementsInterface)
|
||||
{
|
||||
if ((!ignoreErrors) && (PreFail()))
|
||||
|
@ -10601,6 +10678,7 @@ void BfModule::ClearConstData()
|
|||
mStringObjectPool.Clear();
|
||||
mStringCharPtrPool.Clear();
|
||||
mStringPoolRefs.Clear();
|
||||
mUnreifiedStringPoolRefs.Clear();
|
||||
}
|
||||
|
||||
BfTypedValue BfModule::GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType)
|
||||
|
@ -10630,17 +10708,18 @@ BfTypedValue BfModule::GetTypedValueFromConstant(BfConstant* constant, BfIRConst
|
|||
auto constVal = mBfIRBuilder->CreateConst(constant, constHolder);
|
||||
BfTypedValue typedValue;
|
||||
|
||||
bool allowUnactualized = mBfIRBuilder->mIgnoreWrites;
|
||||
if (constant->mTypeCode == BfTypeCode_StringId)
|
||||
{
|
||||
if ((wantType->IsInstanceOf(mCompiler->mStringTypeDef)) ||
|
||||
((wantType->IsPointer()) && (wantType->GetUnderlyingType() == GetPrimitiveType(BfTypeCode_Char8))))
|
||||
{
|
||||
typedValue = BfTypedValue(ConstantToCurrent(constant, constHolder, wantType), wantType);
|
||||
typedValue = BfTypedValue(ConstantToCurrent(constant, constHolder, wantType, allowUnactualized), wantType);
|
||||
return typedValue;
|
||||
}
|
||||
|
||||
auto stringType = ResolveTypeDef(mCompiler->mStringTypeDef);
|
||||
typedValue = BfTypedValue(ConstantToCurrent(constant, constHolder, stringType), stringType);
|
||||
typedValue = BfTypedValue(ConstantToCurrent(constant, constHolder, stringType, allowUnactualized), stringType);
|
||||
}
|
||||
|
||||
if (!typedValue)
|
||||
|
@ -10684,7 +10763,27 @@ BfTypedValue BfModule::GetTypedValueFromConstant(BfConstant* constant, BfIRConst
|
|||
return BfTypedValue(irValue, wantType, false);
|
||||
}
|
||||
|
||||
BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType, bool allowStringId)
|
||||
bool BfModule::HasUnactializedConstant(BfConstant* constant, BfIRConstHolder* constHolder)
|
||||
{
|
||||
if ((constant->mConstType == BfConstType_TypeOf) || (constant->mConstType == BfConstType_TypeOf_WithData))
|
||||
return true;
|
||||
if (constant->mTypeCode == BfTypeCode_StringId)
|
||||
return true;
|
||||
|
||||
if (constant->mConstType == BfConstType_Agg)
|
||||
{
|
||||
auto constArray = (BfConstantAgg*)constant;
|
||||
for (auto val : constArray->mValues)
|
||||
{
|
||||
if (HasUnactializedConstant(constHolder->GetConstant(val), constHolder))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType, bool allowUnactualized)
|
||||
{
|
||||
if (constant->mTypeCode == BfTypeCode_NullPtr)
|
||||
{
|
||||
|
@ -10699,20 +10798,27 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con
|
|||
|
||||
if (constant->mTypeCode == BfTypeCode_StringId)
|
||||
{
|
||||
if (!allowStringId)
|
||||
if (!allowUnactualized)
|
||||
{
|
||||
if ((wantType->IsInstanceOf(mCompiler->mStringTypeDef)) ||
|
||||
((wantType->IsPointer()) && (wantType->GetUnderlyingType() == GetPrimitiveType(BfTypeCode_Char8))))
|
||||
{
|
||||
const StringImpl& str = mContext->mStringObjectIdMap[constant->mInt32].mString;
|
||||
BfIRValue stringObjConst = GetStringObjectValue(str);
|
||||
BfIRValue stringObjConst = GetStringObjectValue(str, false, true);
|
||||
if (wantType->IsPointer())
|
||||
return GetStringCharPtr(stringObjConst);
|
||||
return GetStringCharPtr(stringObjConst, true);
|
||||
return stringObjConst;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (constant->mConstType == Beefy::BfConstType_TypeOf)
|
||||
{
|
||||
auto constTypeOf = (BfTypeOf_Const*)constant;
|
||||
AddDependency(constTypeOf->mType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
|
||||
return CreateTypeDataRef(constTypeOf->mType);
|
||||
}
|
||||
|
||||
if (constant->mConstType == BfConstType_Agg)
|
||||
{
|
||||
auto constArray = (BfConstantAgg*)constant;
|
||||
|
@ -10789,6 +10895,9 @@ void BfModule::ValidateCustomAttributes(BfCustomAttributes* customAttributes, Bf
|
|||
|
||||
void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrTarget, bool allowNonConstArgs, BfCaptureInfo* captureInfo)
|
||||
{
|
||||
if (!mCompiler->mHasRequiredTypes)
|
||||
return;
|
||||
|
||||
if ((attributesDirective != NULL) && (mCompiler->mResolvePassData != NULL) &&
|
||||
(attributesDirective->IsFromParser(mCompiler->mResolvePassData->mParser)) && (mCompiler->mResolvePassData->mSourceClassifier != NULL))
|
||||
{
|
||||
|
@ -10908,6 +11017,12 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
|||
continue;
|
||||
}
|
||||
|
||||
if ((mIsReified) && (attrTypeInst->mAttributeData != NULL) && ((attrTypeInst->mAttributeData->mFlags & BfAttributeFlag_ReflectAttribute) != 0))
|
||||
{
|
||||
// Reify attribute
|
||||
PopulateType(attrTypeInst);
|
||||
}
|
||||
|
||||
if (mCurTypeInstance != NULL)
|
||||
AddDependency(attrTypeInst, mCurTypeInstance, BfDependencyMap::DependencyFlag_CustomAttribute);
|
||||
|
||||
|
@ -11018,8 +11133,8 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
|||
|
||||
auto& fieldTypeInst = checkTypeInst->mFieldInstances[bestField->mIdx];
|
||||
if (assignExpr->mRight != NULL)
|
||||
{
|
||||
BfTypedValue result = constResolver.Resolve(assignExpr->mRight, fieldTypeInst.mResolvedType);
|
||||
{
|
||||
BfTypedValue result = constResolver.Resolve(assignExpr->mRight, fieldTypeInst.mResolvedType, BfConstResolveFlag_NoActualizeValues);
|
||||
if (result)
|
||||
{
|
||||
CurrentAddToConstHolder(result.mValue);
|
||||
|
@ -11078,9 +11193,11 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
|||
auto propType = methodInstance.mMethodInstance->GetParamType(0);
|
||||
if (assignExpr->mRight != NULL)
|
||||
{
|
||||
BfTypedValue result = constResolver.Resolve(assignExpr->mRight, propType);
|
||||
if (result)
|
||||
BfTypedValue result = constResolver.Resolve(assignExpr->mRight, propType, BfConstResolveFlag_NoActualizeValues);
|
||||
if ((result) && (!result.mType->IsVar()))
|
||||
{
|
||||
if (!result.mValue.IsConst())
|
||||
result = GetDefaultTypedValue(result.mType);
|
||||
BF_ASSERT(result.mType == propType);
|
||||
CurrentAddToConstHolder(result.mValue);
|
||||
setProperty.mParam = result;
|
||||
|
@ -11092,7 +11209,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
|||
}
|
||||
|
||||
if ((!handledExpr) && (assignExpr->mRight != NULL))
|
||||
constResolver.Resolve(assignExpr->mRight);
|
||||
constResolver.Resolve(assignExpr->mRight, NULL, BfConstResolveFlag_NoActualizeValues);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -11112,7 +11229,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
|||
resolvedArg.mArgFlags = BfArgFlag_DeferredEval;
|
||||
}
|
||||
else
|
||||
resolvedArg.mTypedValue = constResolver.Resolve(arg);
|
||||
resolvedArg.mTypedValue = constResolver.Resolve(arg, NULL, BfConstResolveFlag_NoActualizeValues);
|
||||
|
||||
if (!inPropSet)
|
||||
{
|
||||
|
@ -11193,7 +11310,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
|||
if ((arg.mArgFlags & BfArgFlag_DeferredEval) != 0)
|
||||
{
|
||||
if (auto expr = BfNodeDynCast<BfExpression>(arg.mExpression))
|
||||
constResolver.Resolve(expr);
|
||||
constResolver.Resolve(expr, NULL, BfConstResolveFlag_NoActualizeValues);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11512,14 +11629,17 @@ BfVariant BfModule::TypedValueToVariant(BfAstNode* refNode, const BfTypedValue&
|
|||
case BfTypeCode_UIntPtr:
|
||||
case BfTypeCode_IntUnknown:
|
||||
case BfTypeCode_UIntUnknown:
|
||||
case BfTypeCode_Float:
|
||||
case BfTypeCode_Double:
|
||||
case BfTypeCode_Char8:
|
||||
case BfTypeCode_Char16:
|
||||
case BfTypeCode_Char32:
|
||||
variant.mTypeCode = constant->mTypeCode;
|
||||
variant.mInt64 = constant->mInt64;
|
||||
break;
|
||||
break;
|
||||
case BfTypeCode_Float:
|
||||
variant.mTypeCode = constant->mTypeCode;
|
||||
variant.mSingle = (float)constant->mDouble;
|
||||
break;
|
||||
default:
|
||||
if (refNode != NULL)
|
||||
Fail("Invalid const expression type", refNode);
|
||||
|
@ -13624,6 +13744,13 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance)
|
|||
{
|
||||
globalValue = *globalValuePtr;
|
||||
BF_ASSERT(globalValue);
|
||||
|
||||
auto globalVar = (BfGlobalVar*)mBfIRBuilder->GetConstant(globalValue);
|
||||
if ((globalVar->mStreamId == -1) && (!mBfIRBuilder->mIgnoreWrites))
|
||||
{
|
||||
mBfIRBuilder->MapType(fieldInstance->mResolvedType);
|
||||
mBfIRBuilder->CreateGlobalVariable(globalValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -13655,16 +13782,11 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance)
|
|||
BfIRValue(),
|
||||
staticVarName,
|
||||
IsThreadLocal(fieldInstance));
|
||||
|
||||
if (!mBfIRBuilder->mIgnoreWrites)
|
||||
{
|
||||
// Only store this if we actually did the creation
|
||||
BF_ASSERT(globalValue);
|
||||
mStaticFieldRefs[fieldInstance] = globalValue;
|
||||
}
|
||||
|
||||
BF_ASSERT(globalValue);
|
||||
mStaticFieldRefs[fieldInstance] = globalValue;
|
||||
|
||||
BfLogSysM("Mod:%p Type:%p ReferenceStaticField %p -> %p\n", this, fieldInstance->mOwner, fieldInstance, globalValue);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13676,7 +13798,7 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance)
|
|||
}
|
||||
|
||||
BfTypedValue BfModule::GetThis()
|
||||
{
|
||||
{
|
||||
auto useMethodState = mCurMethodState;
|
||||
while ((useMethodState != NULL) && (useMethodState->mClosureState != NULL) && (useMethodState->mClosureState->mCapturing))
|
||||
{
|
||||
|
@ -13705,33 +13827,6 @@ BfTypedValue BfModule::GetThis()
|
|||
return BfTypedValue();
|
||||
}
|
||||
|
||||
// if (useMethodState->HasNonStaticMixin())
|
||||
// {
|
||||
// auto checkMethodState = useMethodState;
|
||||
// while (checkMethodState != NULL)
|
||||
// {
|
||||
// for (int localIdx = (int)checkMethodState->mLocals.size() - 1; localIdx >= 0; localIdx--)
|
||||
// {
|
||||
// auto varDecl = checkMethodState->mLocals[localIdx];
|
||||
// if (varDecl->mName == "this")
|
||||
// {
|
||||
// varDecl->mReadFromId = useMethodState->GetRootMethodState()->mCurAccessId++;
|
||||
// if (varDecl->mIsSplat)
|
||||
// {
|
||||
// return BfTypedValue(varDecl->mValue, varDecl->mResolvedType, BfTypedValueKind_ThisSplatHead);
|
||||
// }
|
||||
// else if ((varDecl->mResolvedType->IsValueType()) && (varDecl->mAddr))
|
||||
// {
|
||||
// return BfTypedValue(varDecl->mAddr, varDecl->mResolvedType, BfTypedValueKind_ThisAddr);
|
||||
// }
|
||||
// return BfTypedValue(varDecl->mValue, varDecl->mResolvedType, varDecl->mResolvedType->IsValueType() ? BfTypedValueKind_ThisAddr : BfTypedValueKind_ThisValue);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// checkMethodState = checkMethodState->mPrevMethodState;
|
||||
// }
|
||||
// }
|
||||
|
||||
// Check mixin state for 'this'
|
||||
{
|
||||
auto checkMethodState = mCurMethodState;
|
||||
|
@ -14059,8 +14154,10 @@ void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, bool doAli
|
|||
if (mBfIRBuilder->HasDebugLocation())
|
||||
{
|
||||
if ((isConstant) && (!didConstToMem))
|
||||
{
|
||||
localVarDef->mDbgDeclareInst = mBfIRBuilder->DbgInsertValueIntrinsic(localVarDef->mConstValue, diVariable);
|
||||
{
|
||||
BfTypedValue result(localVarDef->mConstValue, localVarDef->mResolvedType);
|
||||
FixValueActualization(result);
|
||||
localVarDef->mDbgDeclareInst = mBfIRBuilder->DbgInsertValueIntrinsic(result.mValue, diVariable);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -15668,7 +15765,11 @@ void BfModule::EmitDtorBody()
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!mCurTypeInstance->IsValueType())
|
||||
if (fieldInst->mResolvedType->IsValuelessType())
|
||||
{
|
||||
value = mBfIRBuilder->GetFakeVal();
|
||||
}
|
||||
else if (!mCurTypeInstance->IsValueType())
|
||||
{
|
||||
auto thisValue = GetThis();
|
||||
value = mBfIRBuilder->CreateInBoundsGEP(thisValue.mValue, 0, fieldInst->mDataIdx);
|
||||
|
@ -15744,13 +15845,7 @@ void BfModule::EmitDtorBody()
|
|||
UpdateSrcPos(typeDef->mTypeDeclaration->mNameNode);
|
||||
}
|
||||
|
||||
checkBaseType->mTypeDef->PopulateMemberSets();
|
||||
BfMemberSetEntry* entry = NULL;
|
||||
BfMethodDef* dtorMethodDef = NULL;
|
||||
checkBaseType->mTypeDef->mMethodSet.TryGetWith(String("~this"), &entry);
|
||||
if (entry != NULL)
|
||||
dtorMethodDef = (BfMethodDef*)entry->mMemberDef;
|
||||
|
||||
BfMethodDef* dtorMethodDef = checkBaseType->mTypeDef->GetMethodByName("~this");
|
||||
if (dtorMethodDef != NULL)
|
||||
{
|
||||
auto dtorMethodInstance = GetMethodInstance(checkBaseType, dtorMethodDef, BfTypeVector());
|
||||
|
@ -18160,7 +18255,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
|||
auto methodDeclaration = methodDef->GetMethodDeclaration();
|
||||
|
||||
if ((methodDef->mHasComptime) && (!mIsComptimeModule))
|
||||
mBfIRBuilder->mIgnoreWrites = true;
|
||||
mBfIRBuilder->mIgnoreWrites = true;
|
||||
|
||||
if ((methodInstance->mIsReified) && (methodInstance->mVirtualTableIdx != -1))
|
||||
{
|
||||
|
@ -18285,7 +18380,36 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
|||
}
|
||||
|
||||
BfLogSysM("ProcessMethod %p Unspecialized: %d Module: %p IRFunction: %d Reified: %d Incomplete:%d\n", methodInstance, mCurTypeInstance->IsUnspecializedType(), this, methodInstance->mIRFunction.mId, methodInstance->mIsReified, mIncompleteMethodCount);
|
||||
|
||||
|
||||
int importStrNum = -1;
|
||||
auto importKind = methodInstance->GetImportKind();
|
||||
if ((!mCompiler->mIsResolveOnly) &&
|
||||
((importKind == BfImportKind_Import_Static) || (importKind == BfImportKind_Import_Dynamic)))
|
||||
{
|
||||
if (auto customAttr = methodInstance->GetCustomAttributes()->Get(mCompiler->mImportAttributeTypeDef))
|
||||
{
|
||||
if (customAttr->mCtorArgs.size() == 1)
|
||||
{
|
||||
auto fileNameArg = customAttr->mCtorArgs[0];
|
||||
auto constant = mCurTypeInstance->mConstHolder->GetConstant(fileNameArg);
|
||||
if (constant != NULL)
|
||||
{
|
||||
if (!constant->IsNull())
|
||||
importStrNum = constant->mInt32;
|
||||
}
|
||||
else
|
||||
{
|
||||
importStrNum = GetStringPoolIdx(fileNameArg, mCurTypeInstance->mConstHolder);
|
||||
}
|
||||
if (importStrNum != -1)
|
||||
{
|
||||
if (!mStringPoolRefs.Contains(importStrNum))
|
||||
mStringPoolRefs.Add(importStrNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (methodInstance->GetImportCallKind() != BfImportCallKind_None)
|
||||
{
|
||||
if (mBfIRBuilder->mIgnoreWrites)
|
||||
|
@ -19451,7 +19575,11 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
|||
}
|
||||
|
||||
auto bodyBlock = BfNodeDynCast<BfBlock>(methodDef->mBody);
|
||||
if (methodDef->mBody == NULL)
|
||||
if (!mCompiler->mHasRequiredTypes)
|
||||
{
|
||||
// Skip processing to avoid errors
|
||||
}
|
||||
else if (methodDef->mBody == NULL)
|
||||
{
|
||||
if (methodDeclaration != NULL)
|
||||
{
|
||||
|
@ -19463,34 +19591,19 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
|||
}
|
||||
|
||||
bool isDllImport = false;
|
||||
if (methodInstance->GetImportKind() == BfImportKind_Import_Static)
|
||||
if ((importKind == BfImportKind_Import_Static) || (importKind == BfImportKind_Import_Dynamic))
|
||||
{
|
||||
for (auto customAttr : methodInstance->GetCustomAttributes()->mAttributes)
|
||||
{
|
||||
if (customAttr.mType->mTypeDef->mFullName.ToString() == "System.ImportAttribute")
|
||||
if (importStrNum != -1)
|
||||
{
|
||||
if (importKind == BfImportKind_Import_Static)
|
||||
{
|
||||
if (customAttr.mCtorArgs.size() == 1)
|
||||
if (!mImportFileNames.Contains(importStrNum))
|
||||
{
|
||||
auto fileNameArg = customAttr.mCtorArgs[0];
|
||||
int strNum = 0;
|
||||
auto constant = mCurTypeInstance->mConstHolder->GetConstant(fileNameArg);
|
||||
if (constant != NULL)
|
||||
{
|
||||
if (constant->IsNull())
|
||||
continue; // Invalid
|
||||
strNum = constant->mInt32;
|
||||
}
|
||||
else
|
||||
{
|
||||
strNum = GetStringPoolIdx(fileNameArg, mCurTypeInstance->mConstHolder);
|
||||
}
|
||||
if (!mImportFileNames.Contains(strNum))
|
||||
mImportFileNames.Add(strNum);
|
||||
mImportFileNames.Add(importStrNum);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//mImportFileNames
|
||||
}
|
||||
else if (methodInstance->GetImportKind() == BfImportKind_Import_Dynamic)
|
||||
{
|
||||
|
@ -21534,6 +21647,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
|||
{
|
||||
BfTypeInstance* unspecializedTypeInstance = NULL;
|
||||
|
||||
Array<BfTypeReference*> deferredResolveTypes;
|
||||
for (int genericParamIdx = 0; genericParamIdx < (int)methodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
|
||||
{
|
||||
auto genericParam = methodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
|
||||
|
@ -21557,8 +21671,8 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
|||
else
|
||||
genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var);
|
||||
}
|
||||
|
||||
ResolveGenericParamConstraints(genericParam, methodInstance->mIsUnspecialized);
|
||||
|
||||
ResolveGenericParamConstraints(genericParam, methodInstance->mIsUnspecialized, &deferredResolveTypes);
|
||||
|
||||
if (genericParamIdx < (int)methodDef->mGenericParams.size())
|
||||
{
|
||||
|
@ -21572,6 +21686,8 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
|||
}
|
||||
}
|
||||
}
|
||||
for (auto typeRef : deferredResolveTypes)
|
||||
auto constraintType = ResolveTypeRef(typeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_None);
|
||||
|
||||
for (auto genericParam : methodInstance->mMethodInfoEx->mGenericParams)
|
||||
{
|
||||
|
@ -21920,6 +22036,12 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
|||
}
|
||||
else
|
||||
{
|
||||
BfTypeState typeState;
|
||||
typeState.mTypeInstance = mCurTypeInstance;
|
||||
typeState.mCurTypeDef = methodDef->mDeclaringType;
|
||||
//typeState.mCurMethodDef = methodDef;
|
||||
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
||||
|
||||
BfConstResolver constResolver(this);
|
||||
defaultValue = constResolver.Resolve(paramDef->mParamDeclaration->mInitializer, resolvedParamType, (BfConstResolveFlags)(BfConstResolveFlag_NoCast | BfConstResolveFlag_AllowGlobalVariable));
|
||||
if ((defaultValue) && (defaultValue.mType != resolvedParamType))
|
||||
|
@ -22051,7 +22173,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
|||
resolvedParamType = CreateArrayType(mContext->mBfObjectType, 1);
|
||||
}
|
||||
|
||||
if (addParams)
|
||||
if ((addParams) && (resolvedParamType != NULL))
|
||||
{
|
||||
BfMethodParam methodParam;
|
||||
methodParam.mResolvedType = resolvedParamType;
|
||||
|
@ -22692,6 +22814,11 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
|||
}
|
||||
}
|
||||
|
||||
if ((methodDef->mIsConcrete) && (!methodInstance->mIsForeignMethodDef) && (!mCurTypeInstance->IsInterface()))
|
||||
{
|
||||
Fail("Only interfaces methods can be declared as 'concrete'", methodDeclaration->mVirtualSpecifier);
|
||||
}
|
||||
|
||||
if ((methodDef->mIsVirtual) && (methodDef->mIsStatic) && (!methodInstance->mIsInnerOverride))
|
||||
{
|
||||
if ((virtualToken != NULL) && (virtualToken->mToken == BfToken_Override) && (methodDef->mDeclaringType->mTypeCode == BfTypeCode_Extension))
|
||||
|
|
|
@ -1435,6 +1435,7 @@ public:
|
|||
Dictionary<int, BfIRValue> mStringObjectPool;
|
||||
Dictionary<int, BfIRValue> mStringCharPtrPool;
|
||||
Array<int> mStringPoolRefs;
|
||||
HashSet<int> mUnreifiedStringPoolRefs;
|
||||
|
||||
Array<BfIRBuilder*> mPrevIRBuilders; // Before extensions
|
||||
BfIRBuilder* mBfIRBuilder;
|
||||
|
@ -1538,12 +1539,12 @@ public:
|
|||
BfIRValue CreateStringCharPtr(const StringImpl& str, int stringId, bool define);
|
||||
int GetStringPoolIdx(BfIRValue constantStr, BfIRConstHolder* constHolder = NULL);
|
||||
String* GetStringPoolString(BfIRValue constantStr, BfIRConstHolder* constHolder = NULL);
|
||||
BfIRValue GetStringCharPtr(int stringId);
|
||||
BfIRValue GetStringCharPtr(BfIRValue strValue);
|
||||
BfIRValue GetStringCharPtr(const StringImpl& str);
|
||||
BfIRValue GetStringObjectValue(int idx);
|
||||
BfIRValue GetStringObjectValue(const StringImpl& str, bool define = false);
|
||||
BfIRValue CreateGlobalConstValue(const StringImpl& name, BfIRValue constant, BfIRType type, bool external);
|
||||
BfIRValue GetStringCharPtr(int stringId, bool force = false);
|
||||
BfIRValue GetStringCharPtr(BfIRValue strValue, bool force = false);
|
||||
BfIRValue GetStringCharPtr(const StringImpl& str, bool force = false);
|
||||
BfIRValue GetStringObjectValue(int idx, bool define, bool force);
|
||||
BfIRValue GetStringObjectValue(const StringImpl& str, bool define = false, bool force = false);
|
||||
BfIRValue CreateGlobalConstValue(const StringImpl& name, BfIRValue constant, BfIRType type, bool external);
|
||||
void VariantToString(StringImpl& str, const BfVariant& variant);
|
||||
StringT<128> TypeToString(BfType* resolvedType, Array<String>* genericMethodParamNameOverrides = NULL);
|
||||
StringT<128> TypeToString(BfType* resolvedType, BfTypeNameFlags typeNameFlags, Array<String>* genericMethodParamNameOverrides = NULL);
|
||||
|
@ -1553,8 +1554,9 @@ public:
|
|||
void pm(BfMethodInstance* type);
|
||||
void CurrentAddToConstHolder(BfIRValue& irVal);
|
||||
void ClearConstData();
|
||||
BfTypedValue GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType);
|
||||
BfIRValue ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType, bool allowStringId = false);
|
||||
bool HasUnactializedConstant(BfConstant* constant, BfIRConstHolder* constHolder);
|
||||
BfTypedValue GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType);
|
||||
BfIRValue ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType, bool allowUnactualized = false);
|
||||
void ValidateCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeTargets attrTarget);
|
||||
void GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs = false, BfCaptureInfo* captureInfo = NULL);
|
||||
BfCustomAttributes* GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs = false, BfCaptureInfo* captureInfo = NULL);
|
||||
|
@ -1771,12 +1773,12 @@ public:
|
|||
BfMethodRefType* CreateMethodRefType(BfMethodInstance* methodInstance, bool mustAlreadyExist = false);
|
||||
BfType* FixIntUnknown(BfType* type);
|
||||
void FixIntUnknown(BfTypedValue& typedVal, BfType* matchType = NULL);
|
||||
void FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs);
|
||||
void FixValueActualization(BfTypedValue& typedVal);
|
||||
void FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs);
|
||||
void FixValueActualization(BfTypedValue& typedVal, bool force = false);
|
||||
bool TypeEquals(BfTypedValue& val, BfType* type);
|
||||
BfTypeDef* ResolveGenericInstanceDef(BfGenericInstanceTypeRef* genericTypeRef, BfType** outType = NULL, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None);
|
||||
BfType* ResolveType(BfType* lookupType, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None);
|
||||
void ResolveGenericParamConstraints(BfGenericParamInstance* genericParamInstance, bool isUnspecialized);
|
||||
void ResolveGenericParamConstraints(BfGenericParamInstance* genericParamInstance, bool isUnspecialized, Array<BfTypeReference*>* deferredResolveTypes = NULL);
|
||||
String GenericParamSourceToString(const BfGenericParamSource& genericParamSource);
|
||||
bool CheckGenericConstraints(const BfGenericParamSource& genericParamSource, BfType* checkArgType, BfAstNode* checkArgTypeRef, BfGenericParamInstance* genericParamInst, BfTypeVector* methodGenericArgs = NULL, BfError** errorOut = NULL);
|
||||
BfIRValue AllocLocalVariable(BfType* type, const StringImpl& name, bool doLifetimeEnd = true);
|
||||
|
|
|
@ -164,7 +164,8 @@ bool BfModule::FinishGenericParams(BfType* resolvedTypeRef)
|
|||
typeState.mResolveKind = BfTypeState::ResolveKind_BuildingGenericParams;
|
||||
typeState.mTypeInstance = resolvedTypeRef->ToTypeInstance();
|
||||
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
||||
|
||||
Array<BfTypeReference*> deferredResolveTypes;
|
||||
|
||||
BF_ASSERT(mCurMethodInstance == NULL);
|
||||
|
||||
auto genericTypeInst = resolvedTypeRef->ToGenericTypeInstance();
|
||||
|
@ -210,7 +211,7 @@ bool BfModule::FinishGenericParams(BfType* resolvedTypeRef)
|
|||
genericParamInstance->mExternType = GetPrimitiveType(BfTypeCode_Var);
|
||||
}
|
||||
|
||||
ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType());
|
||||
ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType(), &deferredResolveTypes);
|
||||
|
||||
if (genericParamDef != NULL)
|
||||
{
|
||||
|
@ -283,7 +284,7 @@ bool BfModule::FinishGenericParams(BfType* resolvedTypeRef)
|
|||
genericParamInstance->mExternType = GetPrimitiveType(BfTypeCode_Var);
|
||||
}
|
||||
|
||||
ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType());
|
||||
ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType(), &deferredResolveTypes);
|
||||
auto genericParamDef = genericParamInstance->GetGenericParamDef();
|
||||
if (genericParamDef != NULL)
|
||||
{
|
||||
|
@ -295,6 +296,9 @@ bool BfModule::FinishGenericParams(BfType* resolvedTypeRef)
|
|||
}
|
||||
}
|
||||
|
||||
for (auto typeRef : deferredResolveTypes)
|
||||
auto constraintType = ResolveTypeRef(typeRef, BfPopulateType_Declaration, BfResolveTypeRefFlag_None);
|
||||
|
||||
for (auto genericParam : genericTypeInst->mGenericTypeInfo->mGenericParams)
|
||||
{
|
||||
for (auto constraintTypeInst : genericParam->mInterfaceConstraints)
|
||||
|
@ -339,6 +343,13 @@ bool BfModule::ValidateGenericConstraints(BfTypeReference* typeRef, BfTypeInstan
|
|||
return true;
|
||||
}
|
||||
|
||||
for (auto typeArg : genericTypeInst->mGenericTypeInfo->mTypeGenericArguments)
|
||||
{
|
||||
auto genericArg = typeArg->ToGenericTypeInstance();
|
||||
if (genericArg != NULL)
|
||||
genericTypeInst->mGenericTypeInfo->mMaxGenericDepth = BF_MAX(genericTypeInst->mGenericTypeInfo->mMaxGenericDepth, genericArg->mGenericTypeInfo->mMaxGenericDepth + 1);
|
||||
}
|
||||
|
||||
auto typeDef = genericTypeInst->mTypeDef;
|
||||
for (int paramIdx = 0; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mGenericParams.size(); paramIdx++)
|
||||
{
|
||||
|
@ -1029,7 +1040,21 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
|
|||
typeModule->mIsReified = true;
|
||||
typeModule->mWantsIRIgnoreWrites = false;
|
||||
for (auto ownedTypes : typeModule->mOwnedTypeInstances)
|
||||
{
|
||||
ownedTypes->mIsReified = true;
|
||||
|
||||
if (ownedTypes->mCustomAttributes != NULL)
|
||||
{
|
||||
for (auto& attr : ownedTypes->mCustomAttributes->mAttributes)
|
||||
{
|
||||
if ((attr.mType->mAttributeData != NULL) && ((attr.mType->mAttributeData->mFlags & BfCustomAttributeFlags_ReflectAttribute) != 0))
|
||||
{
|
||||
// Reify this attribute
|
||||
typeModule->PopulateType(attr.mType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mCompiler->mStats.mReifiedModuleCount++;
|
||||
if (typeModule->mBfIRBuilder != NULL)
|
||||
{
|
||||
|
@ -1038,7 +1063,7 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
|
|||
typeModule->SetupIRBuilder(false);
|
||||
}
|
||||
else
|
||||
typeModule->PrepareForIRWriting(resolvedTypeRef->ToTypeInstance());
|
||||
typeModule->PrepareForIRWriting(resolvedTypeRef->ToTypeInstance());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2002,7 +2027,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance*
|
|||
for (auto& customAttribute : customAttributes->mAttributes)
|
||||
{
|
||||
auto attrType = customAttribute.mType;
|
||||
PopulateType(attrType, BfPopulateType_DataAndMethods);
|
||||
mContext->mUnreifiedModule->PopulateType(attrType, BfPopulateType_DataAndMethods);
|
||||
if (attrType->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted)
|
||||
continue;
|
||||
|
||||
|
@ -2331,7 +2356,7 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance)
|
|||
for (auto& customAttribute : customAttributes->mAttributes)
|
||||
{
|
||||
auto attrType = customAttribute.mType;
|
||||
PopulateType(attrType, BfPopulateType_DataAndMethods);
|
||||
mContext->mUnreifiedModule->PopulateType(attrType, BfPopulateType_DataAndMethods);
|
||||
if (attrType->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted)
|
||||
continue;
|
||||
|
||||
|
@ -2599,8 +2624,10 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeInstance);
|
||||
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
|
||||
SetAndRestoreValue<BfMethodState*> prevMethodState(mCurMethodState, NULL);
|
||||
SetAndRestoreValue<bool> prevHadError(mHadBuildError, false);
|
||||
SetAndRestoreValue<bool> prevHadWarning(mHadBuildWarning, false);
|
||||
|
||||
// WHY were we clearing these values?
|
||||
//SetAndRestoreValue<bool> prevHadError(mHadBuildError, false);
|
||||
//SetAndRestoreValue<bool> prevHadWarning(mHadBuildWarning, false);
|
||||
|
||||
BfTypeState typeState(mCurTypeInstance, mContext->mCurTypeState);
|
||||
typeState.mPopulateType = populateType;
|
||||
|
@ -2640,8 +2667,8 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
|
||||
if (typeInstance->mIsFinishingType)
|
||||
{
|
||||
// This type already failed
|
||||
return;
|
||||
if (typeInstance->mTypeFailed)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!typeInstance->mTypeFailed)
|
||||
|
@ -3006,7 +3033,10 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
bool populateBase = !typeInstance->mTypeFailed;
|
||||
auto checkType = ResolveTypeRef(checkTypeRef, BfPopulateType_Declaration);
|
||||
if ((checkType != NULL) && (!checkType->IsInterface()) && (populateBase))
|
||||
{
|
||||
SetAndRestoreValue<BfTypeInstance*> prevBaseType(mContext->mCurTypeState->mCurBaseType, checkType->ToTypeInstance());
|
||||
PopulateType(checkType, BfPopulateType_Data);
|
||||
}
|
||||
|
||||
if (typeInstance->mDefineState >= BfTypeDefineState_Defined)
|
||||
{
|
||||
|
@ -3387,6 +3417,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
|
||||
for (auto& validateEntry : deferredTypeValidateList)
|
||||
{
|
||||
SetAndRestoreValue<BfTypeReference*> prevAttributeTypeRef(typeState.mCurAttributeTypeRef, validateEntry.mTypeRef);
|
||||
SetAndRestoreValue<bool> ignoreErrors(mIgnoreErrors, mIgnoreErrors | validateEntry.mIgnoreErrors);
|
||||
ValidateGenericConstraints(validateEntry.mTypeRef, validateEntry.mGenericType, false);
|
||||
}
|
||||
|
@ -3742,7 +3773,12 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
|
||||
if (populateChildType)
|
||||
{
|
||||
BF_ASSERT(!resolvedFieldType->IsDataIncomplete());
|
||||
if (resolvedFieldType->IsFinishingType())
|
||||
{
|
||||
AssertErrorState();
|
||||
}
|
||||
else
|
||||
BF_ASSERT(!resolvedFieldType->IsDataIncomplete());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4319,34 +4355,41 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
|
||||
if ((mCompiler->mOptions.mAllowHotSwapping) && (typeInstance->mDefineState < BfTypeDefineState_Defined))
|
||||
{
|
||||
auto hotTypeVersion = typeInstance->mHotTypeData->mTypeVersions.back();
|
||||
|
||||
if ((typeInstance->mBaseType != NULL) && (typeInstance->mBaseType->mHotTypeData != NULL))
|
||||
if (typeInstance->mHotTypeData == NULL)
|
||||
{
|
||||
hotTypeVersion->mMembers.Add(typeInstance->mBaseType->mHotTypeData->GetLatestVersion());
|
||||
BF_ASSERT(typeInstance->mTypeFailed);
|
||||
}
|
||||
|
||||
for (auto& fieldInst : typeInstance->mFieldInstances)
|
||||
else
|
||||
{
|
||||
auto fieldDef = fieldInst.GetFieldDef();
|
||||
if ((fieldDef == NULL) || (fieldDef->mIsStatic))
|
||||
continue;
|
||||
auto depType = fieldInst.mResolvedType;
|
||||
auto hotTypeVersion = typeInstance->mHotTypeData->mTypeVersions.back();
|
||||
|
||||
while (depType->IsSizedArray())
|
||||
depType = ((BfSizedArrayType*)depType)->mElementType;
|
||||
if (depType->IsStruct())
|
||||
if ((typeInstance->mBaseType != NULL) && (typeInstance->mBaseType->mHotTypeData != NULL))
|
||||
{
|
||||
PopulateType(depType);
|
||||
auto depTypeInst = depType->ToTypeInstance();
|
||||
BF_ASSERT(depTypeInst->mHotTypeData != NULL);
|
||||
if (depTypeInst->mHotTypeData != NULL)
|
||||
hotTypeVersion->mMembers.Add(depTypeInst->mHotTypeData->GetLatestVersion());
|
||||
hotTypeVersion->mMembers.Add(typeInstance->mBaseType->mHotTypeData->GetLatestVersion());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto member : hotTypeVersion->mMembers)
|
||||
member->mRefCount++;
|
||||
for (auto& fieldInst : typeInstance->mFieldInstances)
|
||||
{
|
||||
auto fieldDef = fieldInst.GetFieldDef();
|
||||
if ((fieldDef == NULL) || (fieldDef->mIsStatic))
|
||||
continue;
|
||||
auto depType = fieldInst.mResolvedType;
|
||||
|
||||
while (depType->IsSizedArray())
|
||||
depType = ((BfSizedArrayType*)depType)->mElementType;
|
||||
if (depType->IsStruct())
|
||||
{
|
||||
PopulateType(depType);
|
||||
auto depTypeInst = depType->ToTypeInstance();
|
||||
BF_ASSERT(depTypeInst->mHotTypeData != NULL);
|
||||
if (depTypeInst->mHotTypeData != NULL)
|
||||
hotTypeVersion->mMembers.Add(depTypeInst->mHotTypeData->GetLatestVersion());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto member : hotTypeVersion->mMembers)
|
||||
member->mRefCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (typeInstance->mDefineState < BfTypeDefineState_Defined)
|
||||
|
@ -4962,7 +5005,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
|||
|
||||
//
|
||||
{
|
||||
if (typeInstance->IsSpecializedType())
|
||||
if ((typeInstance->IsSpecializedType()) || (typeInstance->IsUnspecializedTypeVariation()))
|
||||
wantsOnDemandMethods = true;
|
||||
else if ((mCompiler->mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_AlwaysInclude) &&
|
||||
(!typeInstance->IsUnspecializedTypeVariation()))
|
||||
|
@ -6000,11 +6043,14 @@ BfArrayType* BfModule::CreateArrayType(BfType* resolvedType, int dimensions)
|
|||
BF_ASSERT(!resolvedType->IsVar());
|
||||
BF_ASSERT(!resolvedType->IsIntUnknown());
|
||||
|
||||
auto arrayTypeDef = mCompiler->GetArrayTypeDef(dimensions);
|
||||
if (arrayTypeDef == NULL)
|
||||
return NULL;
|
||||
auto arrayType = mContext->mArrayTypePool.Get();
|
||||
delete arrayType->mGenericTypeInfo;
|
||||
arrayType->mGenericTypeInfo = new BfGenericTypeInfo();
|
||||
arrayType->mContext = mContext;
|
||||
arrayType->mTypeDef = mCompiler->GetArrayTypeDef(dimensions);
|
||||
arrayType->mTypeDef = arrayTypeDef;
|
||||
arrayType->mDimensions = dimensions;
|
||||
arrayType->mGenericTypeInfo->mTypeGenericArguments.clear();
|
||||
arrayType->mGenericTypeInfo->mTypeGenericArguments.push_back(resolvedType);
|
||||
|
@ -6450,19 +6496,16 @@ void BfModule::FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs)
|
|||
FixIntUnknown(rhs);
|
||||
}
|
||||
|
||||
void BfModule::FixValueActualization(BfTypedValue& typedVal)
|
||||
void BfModule::FixValueActualization(BfTypedValue& typedVal, bool force)
|
||||
{
|
||||
if (!typedVal.mValue.IsConst())
|
||||
return;
|
||||
if (mBfIRBuilder->mIgnoreWrites)
|
||||
if ((mBfIRBuilder->mIgnoreWrites) && (!force))
|
||||
return;
|
||||
auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
|
||||
if (constant->mConstType == BfConstType_TypeOf)
|
||||
{
|
||||
auto constTypeOf = (BfTypeOf_Const*)constant;
|
||||
AddDependency(constTypeOf->mType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
|
||||
typedVal.mValue = CreateTypeDataRef(constTypeOf->mType);
|
||||
}
|
||||
if (!HasUnactializedConstant(constant, mBfIRBuilder))
|
||||
return;
|
||||
typedVal.mValue = ConstantToCurrent(constant, mBfIRBuilder, typedVal.mType, false);
|
||||
}
|
||||
|
||||
BfTypeInstance* BfModule::GetPrimitiveStructType(BfTypeCode typeCode)
|
||||
|
@ -7928,7 +7971,7 @@ bool BfModule::ResolveTypeResult_Validate(BfTypeReference* typeRef, BfType* reso
|
|||
if ((curGenericTypeInstance->mDependencyMap.mMinDependDepth > 32) &&
|
||||
(genericTypeInstance->mDependencyMap.mMinDependDepth > 32))
|
||||
{
|
||||
Fail(StrFormat("Generic type dependency depth exceeded for type '{}'", TypeToString(genericTypeInstance).c_str()), typeRef);
|
||||
Fail(StrFormat("Generic type dependency depth exceeded for type '%s'", TypeToString(genericTypeInstance).c_str()), typeRef);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -9714,7 +9757,14 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
CheckUnspecializedGenericType(genericTypeInst, populateType);
|
||||
resolvedEntry->mValue = genericTypeInst;
|
||||
populateModule->InitType(genericTypeInst, populateType);
|
||||
BF_ASSERT(BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) == resolvedEntry->mHash);
|
||||
#ifdef _DEBUG
|
||||
if (BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) != resolvedEntry->mHash)
|
||||
{
|
||||
int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx);
|
||||
int typeHash = BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx);
|
||||
BF_ASSERT(refHash == typeHash);
|
||||
}
|
||||
#endif
|
||||
return ResolveTypeResult(typeRef, genericTypeInst, populateType, resolveFlags);
|
||||
}
|
||||
}
|
||||
|
@ -9731,6 +9781,11 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
}
|
||||
typeInst->mTypeDef = typeDef;
|
||||
|
||||
if (((resolveFlags & BfResolveTypeRefFlag_NoReify) != 0) && (mCompiler->mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_AlwaysInclude))
|
||||
{
|
||||
typeInst->mIsReified = false;
|
||||
}
|
||||
|
||||
if (typeInst->mTypeDef->mGenericParamDefs.size() != 0)
|
||||
{
|
||||
Fail("Generic type arguments expected", typeRef);
|
||||
|
@ -9767,12 +9822,13 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
}
|
||||
|
||||
auto elementType = ResolveTypeRef(arrayTypeRef->mElementType, BfPopulateType_Declaration, BfResolveTypeRefFlag_AllowGenericParamConstValue);
|
||||
if (elementType == NULL)
|
||||
auto arrayTypeDef = mCompiler->GetArrayTypeDef(arrayTypeRef->mDimensions);
|
||||
if ((elementType == NULL) || (arrayTypeDef == NULL))
|
||||
{
|
||||
mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
|
||||
return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
|
||||
}
|
||||
|
||||
|
||||
if ((arrayTypeRef->mDimensions == 1) && (arrayTypeRef->mParams.size() == 1))
|
||||
{
|
||||
intptr elementCount = -1;
|
||||
|
@ -9840,7 +9896,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
arrayType->mGenericTypeInfo = new BfGenericTypeInfo();
|
||||
arrayType->mContext = mContext;
|
||||
arrayType->mDimensions = arrayTypeRef->mDimensions;
|
||||
arrayType->mTypeDef = mCompiler->GetArrayTypeDef(arrayType->mDimensions);
|
||||
arrayType->mTypeDef = arrayTypeDef;
|
||||
arrayType->mGenericTypeInfo->mTypeGenericArguments.push_back(elementType);
|
||||
resolvedEntry->mValue = arrayType;
|
||||
|
||||
|
@ -9962,15 +10018,16 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
auto parentTypeInstance = outerTypeInstance;
|
||||
if (parentTypeInstance->IsTypeAlias())
|
||||
parentTypeInstance = (BfTypeInstance*)GetOuterType(parentTypeInstance)->ToTypeInstance();
|
||||
genericTypeInst->mGenericTypeInfo->mMaxGenericDepth = BF_MAX(genericTypeInst->mGenericTypeInfo->mMaxGenericDepth, parentTypeInstance->mGenericTypeInfo->mMaxGenericDepth);
|
||||
for (int i = 0; i < startDefGenericParamIdx; i++)
|
||||
{
|
||||
genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(parentTypeInstance->mGenericTypeInfo->mGenericParams[i]->AddRef());
|
||||
genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]);
|
||||
auto typeGenericArg = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[i];
|
||||
genericTypeInst->mGenericTypeInfo->mIsUnspecialized |= typeGenericArg->IsGenericParam() || typeGenericArg->IsUnspecializedType();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int wantedGenericParams = genericParamCount - startDefGenericParamIdx;
|
||||
int genericArgDiffCount = (int)genericArguments.size() - wantedGenericParams;
|
||||
|
@ -9989,14 +10046,28 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
for (auto genericArgRef : genericArguments)
|
||||
{
|
||||
auto genericArg = genericArgs[genericParamIdx + startDefGenericParamIdx];
|
||||
|
||||
if (auto genericGenericArg = genericArg->ToGenericTypeInstance())
|
||||
{
|
||||
genericTypeInst->mGenericTypeInfo->mMaxGenericDepth = BF_MAX(genericTypeInst->mGenericTypeInfo->mMaxGenericDepth, genericGenericArg->mGenericTypeInfo->mMaxGenericDepth + 1);
|
||||
}
|
||||
|
||||
genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(genericArg);
|
||||
genericTypeInst->mGenericTypeInfo->mTypeGenericArgumentRefs.push_back(genericArgRef);
|
||||
|
||||
genericParamIdx++;
|
||||
}
|
||||
|
||||
resolvedEntry->mValue = genericTypeInst;
|
||||
if (genericTypeInst->mGenericTypeInfo->mMaxGenericDepth > 64)
|
||||
{
|
||||
Fail("Maximum generic depth exceeded", typeRef);
|
||||
delete genericTypeInst;
|
||||
mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
|
||||
return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
|
||||
}
|
||||
|
||||
resolvedEntry->mValue = genericTypeInst;
|
||||
|
||||
CheckUnspecializedGenericType(genericTypeInst, populateType);
|
||||
populateModule->InitType(genericTypeInst, populateType);
|
||||
|
||||
|
@ -10011,6 +10082,8 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
{
|
||||
BF_ASSERT(BfResolvedTypeSet::Equals(genericTypeInst, typeRef, &lookupCtx));
|
||||
}
|
||||
|
||||
BfLogSysM("Generic type %p typeHash: %8X\n", genericTypeInst, resolvedEntry->mHash);
|
||||
#endif
|
||||
|
||||
BF_ASSERT(BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) == resolvedEntry->mHash);
|
||||
|
@ -10145,7 +10218,14 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
CheckUnspecializedGenericType(genericTypeInst, populateType);
|
||||
|
||||
resolvedEntry->mValue = genericTypeInst;
|
||||
BF_ASSERT(BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) == resolvedEntry->mHash);
|
||||
#ifdef _DEBUG
|
||||
if (BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) != resolvedEntry->mHash)
|
||||
{
|
||||
int refHash = BfResolvedTypeSet::Hash(typeRef, &lookupCtx);
|
||||
int typeHash = BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx);
|
||||
BF_ASSERT(refHash == typeHash);
|
||||
}
|
||||
#endif
|
||||
populateModule->InitType(genericTypeInst, populateType);
|
||||
return ResolveTypeResult(typeRef, genericTypeInst, populateType, resolveFlags);
|
||||
}
|
||||
|
@ -10281,7 +10361,11 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
if ((mCurTypeInstance == NULL) || (!mCurTypeInstance->IsGenericTypeInstance()))
|
||||
wantGeneric = false;
|
||||
|
||||
auto baseDelegateType = ResolveTypeDef(mCompiler->mDelegateTypeDef)->ToTypeInstance();
|
||||
BfTypeInstance* baseDelegateType = NULL;
|
||||
if (mCompiler->mDelegateTypeDef != NULL)
|
||||
baseDelegateType = ResolveTypeDef(mCompiler->mDelegateTypeDef)->ToTypeInstance();
|
||||
else
|
||||
failed = true;
|
||||
|
||||
BfDelegateInfo* delegateInfo = NULL;
|
||||
BfTypeInstance* delegateType = NULL;
|
||||
|
@ -10328,7 +10412,8 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
Val128 hashContext;
|
||||
|
||||
BfTypeDef* typeDef = new BfTypeDef();
|
||||
typeDef->mProject = baseDelegateType->mTypeDef->mProject;
|
||||
if (baseDelegateType != NULL)
|
||||
typeDef->mProject = baseDelegateType->mTypeDef->mProject;
|
||||
typeDef->mSystem = mCompiler->mSystem;
|
||||
typeDef->mName = mSystem->mEmptyAtom;
|
||||
if (delegateTypeRef->mTypeToken->GetToken() == BfToken_Delegate)
|
||||
|
@ -10360,9 +10445,12 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
|||
delegateInfo->mDirectAllocNodes.push_back(directTypeRef);
|
||||
if (typeDef->mIsDelegate)
|
||||
directTypeRef->Init(delegateType);
|
||||
else if (mCompiler->mFunctionTypeDef == NULL)
|
||||
failed = true;
|
||||
else
|
||||
directTypeRef->Init(ResolveTypeDef(mCompiler->mFunctionTypeDef));
|
||||
typeDef->mBaseTypes.push_back(directTypeRef);
|
||||
if (!failed)
|
||||
typeDef->mBaseTypes.push_back(directTypeRef);
|
||||
|
||||
directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
|
||||
delegateInfo->mDirectAllocNodes.push_back(directTypeRef);
|
||||
|
@ -11013,7 +11101,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
{
|
||||
SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true);
|
||||
auto constraintTypeInst = genericParamInst->mTypeConstraint->ToTypeInstance();
|
||||
if ((constraintTypeInst != NULL) && (constraintTypeInst->mTypeDef == mCompiler->mEnumTypeDef))
|
||||
if ((constraintTypeInst != NULL) && (constraintTypeInst->mTypeDef == mCompiler->mEnumTypeDef) && (explicitCast))
|
||||
{
|
||||
// Enum->int
|
||||
if ((explicitCast) && (toType->IsInteger()))
|
||||
|
@ -11052,7 +11140,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
}
|
||||
}
|
||||
|
||||
if (toType->IsInteger())
|
||||
if ((toType->IsInteger()) && (explicitCast))
|
||||
{
|
||||
if ((genericParamInst->mGenericParamFlags & BfGenericParamFlag_Enum) != 0)
|
||||
{
|
||||
|
@ -12780,6 +12868,19 @@ bool BfModule::TypeIsSubTypeOf(BfTypeInstance* srcType, BfTypeInstance* wantType
|
|||
|
||||
if (srcType->mDefineState < BfTypeDefineState_HasInterfaces)
|
||||
{
|
||||
if (srcType->mDefineState == BfTypeDefineState_ResolvingBaseType)
|
||||
{
|
||||
auto typeState = mContext->mCurTypeState;
|
||||
while (typeState != NULL)
|
||||
{
|
||||
if ((typeState->mTypeInstance == srcType) && (typeState->mCurBaseType != NULL))
|
||||
{
|
||||
return TypeIsSubTypeOf(typeState->mCurBaseType, wantType, checkAccessibility);
|
||||
}
|
||||
typeState = typeState->mPrevState;
|
||||
}
|
||||
}
|
||||
|
||||
// Type is incomplete. We don't do the IsIncomplete check here because of re-entry
|
||||
// While handling 'var' resolution, we don't want to force a PopulateType reentry
|
||||
// but we do have enough information for TypeIsSubTypeOf
|
||||
|
|
|
@ -374,6 +374,50 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node)
|
|||
{
|
||||
Visit((BfAstNode*)node);
|
||||
startIdx = node->mSrcStart;
|
||||
|
||||
if (doWrap)
|
||||
{
|
||||
bool wantWrap = false;
|
||||
|
||||
int spacedWordCount = 0;
|
||||
bool inQuotes = false;
|
||||
auto src = astNodeSrc->mSrc;
|
||||
bool isDefinitelyCode = false;
|
||||
bool hadNonSlash = false;
|
||||
|
||||
for (int i = node->mSrcStart + 1; i < node->mSrcEnd - 1; i++)
|
||||
{
|
||||
char c = src[i];
|
||||
if (c != '/')
|
||||
hadNonSlash = true;
|
||||
if (inQuotes)
|
||||
{
|
||||
if (c == '\\')
|
||||
{
|
||||
i++;
|
||||
}
|
||||
else if (c == '\"')
|
||||
{
|
||||
inQuotes = false;
|
||||
}
|
||||
}
|
||||
else if (c == '"')
|
||||
{
|
||||
inQuotes = true;
|
||||
}
|
||||
else if (c == ' ')
|
||||
{
|
||||
if ((isalpha((uint8)src[i - 1])) && (isalpha((uint8)src[i + 1])))
|
||||
spacedWordCount++;
|
||||
}
|
||||
else if ((c == '/') && (src[i - 1] == '/') && (hadNonSlash))
|
||||
isDefinitelyCode = true;
|
||||
}
|
||||
|
||||
// If this doesn't look like a sentence then don't try to word wrap
|
||||
if ((isDefinitelyCode) || (spacedWordCount < 4))
|
||||
doWrap = false;
|
||||
}
|
||||
}
|
||||
|
||||
int lineEmittedChars = 0;
|
||||
|
@ -1803,7 +1847,7 @@ void BfPrinter::Visit(BfDeferStatement* deferStmt)
|
|||
|
||||
VisitChild(deferStmt->mDeferToken);
|
||||
VisitChild(deferStmt->mColonToken);
|
||||
VisitChild(deferStmt->mScopeToken);
|
||||
VisitChild(deferStmt->mScopeName);
|
||||
|
||||
if (deferStmt->mBind != NULL)
|
||||
{
|
||||
|
|
|
@ -3797,6 +3797,8 @@ BfAstNode* BfReducer::DoCreateStatement(BfAstNode* node, CreateStmtFlags createS
|
|||
}
|
||||
else if (nextTokenNode->GetToken() == BfToken_LParen)
|
||||
{
|
||||
mPassInstance->Warn(0, "Syntax deprecated", nextTokenNode);
|
||||
|
||||
MEMBER_SET(deferStmt, mOpenParen, nextTokenNode);
|
||||
mVisitorPos.MoveNext();
|
||||
|
||||
|
@ -9264,9 +9266,9 @@ bool BfReducer::ParseMethod(BfMethodDeclaration* methodDeclaration, SizedArrayIm
|
|||
|
||||
bool isFunction = false;
|
||||
bool isDelegate = false;
|
||||
if ((mCurTypeDecl->mTypeNode != NULL) && (mCurTypeDecl->mTypeNode->GetToken() == BfToken_Function))
|
||||
if ((mCurTypeDecl != NULL) && (mCurTypeDecl->mTypeNode != NULL) && (mCurTypeDecl->mTypeNode->GetToken() == BfToken_Function))
|
||||
isFunction = true;
|
||||
else if ((mCurTypeDecl->mTypeNode != NULL) && (mCurTypeDecl->mTypeNode->GetToken() == BfToken_Delegate))
|
||||
else if ((mCurTypeDecl != NULL) && (mCurTypeDecl->mTypeNode != NULL) && (mCurTypeDecl->mTypeNode->GetToken() == BfToken_Delegate))
|
||||
isDelegate = true;
|
||||
|
||||
if ((!isFunction) && (!isDelegate))
|
||||
|
|
|
@ -1686,7 +1686,7 @@ BfType* BfTypeInstance::GetUnionInnerType(bool* wantSplat)
|
|||
{
|
||||
SetAndRestoreValue<BfFieldDef*> prevTypeRef(mContext->mCurTypeState->mCurFieldDef, fieldDef);
|
||||
|
||||
mModule->PopulateType(checkInnerType);
|
||||
mModule->PopulateType(checkInnerType, checkInnerType->IsValueType() ? BfPopulateType_Data : BfPopulateType_Declaration);
|
||||
if (checkInnerType->mSize > unionSize)
|
||||
unionSize = checkInnerType->mSize;
|
||||
|
||||
|
@ -2194,7 +2194,7 @@ bool BfTypeInstance::WantsGCMarking()
|
|||
return true;
|
||||
if ((IsEnum()) && (!IsPayloadEnum()))
|
||||
return false;
|
||||
BF_ASSERT(mDefineState >= BfTypeDefineState_Defined);
|
||||
BF_ASSERT((mDefineState >= BfTypeDefineState_Defined) || (mTypeFailed));
|
||||
return mWantsGCMarking;
|
||||
}
|
||||
|
||||
|
@ -2674,7 +2674,7 @@ size_t BfTypeVectorHash::operator()(const BfTypeVector& typeVec) const
|
|||
size_t hash = typeVec.size();
|
||||
BfResolvedTypeSet::LookupContext ctx;
|
||||
for (auto type : typeVec)
|
||||
hash = ((hash ^ BfResolvedTypeSet::Hash(type, &ctx)) << 5) - hash;
|
||||
hash = ((hash ^ BfResolvedTypeSet::Hash(type, &ctx, Beefy::BfResolvedTypeSet::BfHashFlag_None, 0)) << 5) - hash;
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
@ -2721,6 +2721,8 @@ BfResolvedTypeSet::~BfResolvedTypeSet()
|
|||
|
||||
}
|
||||
|
||||
#define HASH_MIX(origHashVal, newHashVal) ((((origHashVal) << 5) - (origHashVal)) ^ (newHashVal))
|
||||
|
||||
#define HASH_VAL_PTR 1
|
||||
#define HASH_VAL_BOXED 2
|
||||
#define HASH_VAL_REF 3
|
||||
|
@ -2767,7 +2769,7 @@ BfVariant BfResolvedTypeSet::EvaluateToVariant(LookupContext* ctx, BfExpression*
|
|||
return variant;
|
||||
}
|
||||
|
||||
int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
|
||||
int BfResolvedTypeSet::DoHash(BfType* type, LookupContext* ctx, bool allowRef, int hashSeed)
|
||||
{
|
||||
//BP_ZONE("BfResolvedTypeSet::Hash");
|
||||
|
||||
|
@ -2787,13 +2789,13 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
|
|||
if (type->IsBoxed())
|
||||
{
|
||||
BfBoxedType* boxedType = (BfBoxedType*)type;
|
||||
int elemHash = Hash(boxedType->mElementType, ctx) ^ HASH_VAL_BOXED;
|
||||
int elemHash = Hash(boxedType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ HASH_VAL_BOXED;
|
||||
return (elemHash << 5) - elemHash;
|
||||
}
|
||||
else if (type->IsArray())
|
||||
{
|
||||
BfArrayType* arrayType = (BfArrayType*)type;
|
||||
int elemHash = Hash(arrayType->mGenericTypeInfo->mTypeGenericArguments[0], ctx) ^ (arrayType->mDimensions << 8);
|
||||
int elemHash = Hash(arrayType->mGenericTypeInfo->mTypeGenericArguments[0], ctx, BfHashFlag_None, hashSeed) ^ (arrayType->mDimensions << 8);
|
||||
return (elemHash << 5) - elemHash;
|
||||
}
|
||||
else if (type->IsDelegateFromTypeRef() || type->IsFunctionFromTypeRef())
|
||||
|
@ -2803,7 +2805,7 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
|
|||
|
||||
auto delegateInfo = type->GetDelegateInfo();
|
||||
|
||||
hashVal = ((hashVal ^ (Hash(delegateInfo->mReturnType, ctx))) << 5) - hashVal;
|
||||
hashVal = ((hashVal ^ (Hash(delegateInfo->mReturnType, ctx, BfHashFlag_None, hashSeed))) << 5) - hashVal;
|
||||
|
||||
auto methodDef = typeInst->mTypeDef->mMethods[0];
|
||||
BF_ASSERT(methodDef->mName == "Invoke");
|
||||
|
@ -2817,7 +2819,7 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
|
|||
for (int paramIdx = 0; paramIdx < delegateInfo->mParams.size(); paramIdx++)
|
||||
{
|
||||
// Parse attributes?
|
||||
hashVal = ((hashVal ^ (Hash(delegateInfo->mParams[paramIdx], ctx))) << 5) - hashVal;
|
||||
hashVal = ((hashVal ^ (Hash(delegateInfo->mParams[paramIdx], ctx, BfHashFlag_None, hashSeed))) << 5) - hashVal;
|
||||
String paramName = methodDef->mParams[paramIdx]->mName;
|
||||
int nameHash = (int)Hash64(paramName.c_str(), (int)paramName.length());
|
||||
hashVal = ((hashVal ^ (nameHash)) << 5) - hashVal;
|
||||
|
@ -2852,7 +2854,7 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
|
|||
BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
|
||||
|
||||
auto fieldType = fieldInstance->mResolvedType;
|
||||
hashVal = ((hashVal ^ (Hash(fieldType, ctx))) << 5) - hashVal;
|
||||
hashVal = ((hashVal ^ (Hash(fieldType, ctx, BfHashFlag_None, hashSeed))) << 5) - hashVal;
|
||||
BfFieldDef* fieldDef = NULL;
|
||||
if (tupleType->mTypeDef != NULL)
|
||||
fieldDef = fieldInstance->GetFieldDef();
|
||||
|
@ -2873,8 +2875,8 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
|
|||
else if (type->IsGenericTypeInstance())
|
||||
{
|
||||
BfTypeInstance* genericType = (BfTypeInstance*)type;
|
||||
for (auto genericArg : genericType->mGenericTypeInfo->mTypeGenericArguments)
|
||||
hashVal = ((hashVal ^ (Hash(genericArg, ctx))) << 5) - hashVal;
|
||||
for (auto genericArg : genericType->mGenericTypeInfo->mTypeGenericArguments)
|
||||
hashVal = HASH_MIX(hashVal, Hash(genericArg, ctx, BfHashFlag_None, hashSeed + 1));
|
||||
}
|
||||
return hashVal;
|
||||
}
|
||||
|
@ -2886,7 +2888,7 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
|
|||
else if (type->IsPointer())
|
||||
{
|
||||
BfPointerType* pointerType = (BfPointerType*) type;
|
||||
int elemHash = Hash(pointerType->mElementType, ctx) ^ HASH_VAL_PTR;
|
||||
int elemHash = Hash(pointerType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ HASH_VAL_PTR;
|
||||
return (elemHash << 5) - elemHash;
|
||||
}
|
||||
else if (type->IsGenericParam())
|
||||
|
@ -2897,30 +2899,30 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
|
|||
else if (type->IsRef())
|
||||
{
|
||||
auto refType = (BfRefType*)type;
|
||||
int elemHash = Hash(refType->mElementType, ctx) ^ (HASH_VAL_REF + (int)refType->mRefKind);
|
||||
int elemHash = Hash(refType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ (HASH_VAL_REF + (int)refType->mRefKind);
|
||||
return (elemHash << 5) - elemHash;
|
||||
}
|
||||
else if (type->IsModifiedTypeType())
|
||||
{
|
||||
auto modifiedTypeType = (BfModifiedTypeType*)type;
|
||||
int elemHash = Hash(modifiedTypeType->mElementType, ctx) ^ HASH_MODTYPE + (int)modifiedTypeType->mModifiedKind;
|
||||
int elemHash = Hash(modifiedTypeType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ HASH_MODTYPE + (int)modifiedTypeType->mModifiedKind;
|
||||
return (elemHash << 5) - elemHash;
|
||||
}
|
||||
else if (type->IsConcreteInterfaceType())
|
||||
{
|
||||
auto concreteInterfaceType = (BfConcreteInterfaceType*)type;
|
||||
int elemHash = Hash(concreteInterfaceType->mInterface, ctx) ^ HASH_CONCRETE_INTERFACE;
|
||||
int elemHash = Hash(concreteInterfaceType->mInterface, ctx, BfHashFlag_None, hashSeed) ^ HASH_CONCRETE_INTERFACE;
|
||||
return (elemHash << 5) - elemHash;
|
||||
}
|
||||
else if (type->IsSizedArray())
|
||||
{
|
||||
auto sizedArray = (BfSizedArrayType*)type;
|
||||
int elemHash = Hash(sizedArray->mElementType, ctx) ^ HASH_SIZED_ARRAY;
|
||||
int elemHash = Hash(sizedArray->mElementType, ctx, BfHashFlag_None, hashSeed) ^ HASH_SIZED_ARRAY;
|
||||
int hashVal = (elemHash << 5) - elemHash;
|
||||
if (type->IsUnknownSizedArrayType())
|
||||
{
|
||||
auto unknownSizedArray = (BfUnknownSizedArrayType*)type;
|
||||
int elemHash = Hash(unknownSizedArray->mElementCountSource, ctx);
|
||||
int elemHash = Hash(unknownSizedArray->mElementCountSource, ctx, BfHashFlag_None, hashSeed);
|
||||
hashVal = ((hashVal ^ elemHash) << 5) - hashVal;
|
||||
}
|
||||
else
|
||||
|
@ -2940,7 +2942,7 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
|
|||
{
|
||||
BfConstExprValueType* constExprValueType = (BfConstExprValueType*)type;
|
||||
int hashVal = ((int)constExprValueType->mValue.mTypeCode << 17) ^ (constExprValueType->mValue.mInt32 << 3) ^ HASH_CONSTTYPE;
|
||||
hashVal = ((hashVal ^ (Hash(constExprValueType->mType, ctx, BfHashFlag_AllowRef))) << 5) - hashVal;
|
||||
hashVal = ((hashVal ^ (Hash(constExprValueType->mType, ctx, BfHashFlag_AllowRef, hashSeed))) << 5) - hashVal;
|
||||
return hashVal;
|
||||
}
|
||||
else
|
||||
|
@ -2950,21 +2952,29 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void BfResolvedTypeSet::HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hashVal)
|
||||
int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef, int hashSeed)
|
||||
{
|
||||
int hashVal = DoHash(type, ctx, allowRef, hashSeed);
|
||||
if (hashSeed == 0)
|
||||
return hashVal;
|
||||
return HASH_MIX(hashVal, hashSeed);
|
||||
}
|
||||
|
||||
void BfResolvedTypeSet::HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hashVal, int hashSeed)
|
||||
{
|
||||
if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(typeRef))
|
||||
{
|
||||
HashGenericArguments(elementedTypeRef->mElementType, ctx, hashVal);
|
||||
HashGenericArguments(elementedTypeRef->mElementType, ctx, hashVal, hashSeed);
|
||||
}
|
||||
else if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
|
||||
{
|
||||
HashGenericArguments(qualifiedTypeRef->mLeft, ctx, hashVal);
|
||||
HashGenericArguments(qualifiedTypeRef->mLeft, ctx, hashVal, hashSeed);
|
||||
}
|
||||
|
||||
if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
|
||||
{
|
||||
for (auto genericArg : genericTypeRef->mGenericArguments)
|
||||
hashVal = ((hashVal ^ (Hash(genericArg, ctx, BfHashFlag_AllowGenericParamConstValue))) << 5) - hashVal;
|
||||
hashVal = HASH_MIX(hashVal, Hash(genericArg, ctx, BfHashFlag_AllowGenericParamConstValue, hashSeed + 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2976,7 +2986,7 @@ static int HashNode(BfAstNode* node)
|
|||
return (int)Hash64(nameStr, node->GetSrcLength());
|
||||
}
|
||||
|
||||
int BfResolvedTypeSet::DirectHash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags)
|
||||
int BfResolvedTypeSet::DirectHash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags, int hashSeed)
|
||||
{
|
||||
bool isHeadType = typeRef == ctx->mRootTypeRef;
|
||||
|
||||
|
@ -2990,7 +3000,7 @@ int BfResolvedTypeSet::DirectHash(BfTypeReference* typeRef, LookupContext* ctx,
|
|||
ctx->mFailed = true;
|
||||
return 0;
|
||||
}
|
||||
return Hash(resolvedType, ctx);
|
||||
return Hash(resolvedType, ctx, BfHashFlag_None, hashSeed);
|
||||
}
|
||||
|
||||
BfTypeDef* BfResolvedTypeSet::FindRootCommonOuterType(BfTypeDef* outerType, LookupContext* ctx, BfTypeInstance*& outOuterTypeInstance)
|
||||
|
@ -3020,7 +3030,7 @@ BfTypeDef* BfResolvedTypeSet::FindRootCommonOuterType(BfTypeDef* outerType, Look
|
|||
return commonOuterType;
|
||||
}
|
||||
|
||||
int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags)
|
||||
int BfResolvedTypeSet::DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags, int& hashSeed)
|
||||
{
|
||||
if ((typeRef == ctx->mRootTypeRef) && (ctx->mRootTypeDef != NULL) &&
|
||||
((typeRef->IsNamedTypeReference()) || (BfNodeIsA<BfDirectTypeDefReference>(typeRef))))
|
||||
|
@ -3072,8 +3082,8 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
auto curGenericTypeInst = (BfTypeInstance*)checkTypeInstance;
|
||||
int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size();
|
||||
for (int i = 0; i < numParentGenericParams; i++)
|
||||
{
|
||||
hashVal = ((hashVal ^ (Hash(curGenericTypeInst->mGenericTypeInfo->mTypeGenericArguments[i], ctx))) << 5) - hashVal;
|
||||
{
|
||||
hashVal = HASH_MIX(hashVal, Hash(curGenericTypeInst->mGenericTypeInfo->mTypeGenericArguments[i], ctx, BfHashFlag_None, hashSeed + 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3082,7 +3092,9 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
|
||||
if (typeRef->IsNamedTypeReference())
|
||||
{
|
||||
return DirectHash(typeRef, ctx, flags);
|
||||
int hashVal = DirectHash(typeRef, ctx, flags, hashSeed);
|
||||
hashSeed = 0;
|
||||
return hashVal;
|
||||
}
|
||||
if (auto genericInstTypeRef = BfNodeDynCastExact<BfGenericInstanceTypeRef>(typeRef))
|
||||
{
|
||||
|
@ -3124,7 +3136,9 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
ctx->mFailed = true;
|
||||
return 0;
|
||||
}
|
||||
return Hash(underlyingType, ctx, flags);
|
||||
int hashVal = Hash(underlyingType, ctx, flags, hashSeed);
|
||||
hashSeed = 0;
|
||||
return hashVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3155,23 +3169,23 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
{
|
||||
auto parentTypeInstance = checkTypeInstance;
|
||||
int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size();
|
||||
for (int i = 0; i < numParentGenericParams; i++)
|
||||
hashVal = ((hashVal ^ (Hash(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i], ctx))) << 5) - hashVal;
|
||||
for (int i = 0; i < numParentGenericParams; i++)
|
||||
hashVal = HASH_MIX(hashVal, Hash(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i], ctx, Beefy::BfResolvedTypeSet::BfHashFlag_None, hashSeed + 1));
|
||||
}
|
||||
}
|
||||
|
||||
HashGenericArguments(genericInstTypeRef, ctx, hashVal);
|
||||
HashGenericArguments(genericInstTypeRef, ctx, hashVal, hashSeed);
|
||||
|
||||
return hashVal;
|
||||
}
|
||||
else if (auto tupleTypeRef = BfNodeDynCastExact<BfTupleTypeRef>(typeRef))
|
||||
{
|
||||
{
|
||||
int hashVal = HASH_VAL_TUPLE;
|
||||
|
||||
for (int fieldIdx = 0; fieldIdx < (int)tupleTypeRef->mFieldTypes.size(); fieldIdx++)
|
||||
{
|
||||
BfTypeReference* fieldType = tupleTypeRef->mFieldTypes[fieldIdx];
|
||||
hashVal = ((hashVal ^ (Hash(fieldType, ctx))) << 5) - hashVal;
|
||||
hashVal = ((hashVal ^ (Hash(fieldType, ctx, BfHashFlag_None, hashSeed))) << 5) - hashVal;
|
||||
|
||||
int nameHash = 0;
|
||||
BfIdentifierNode* fieldName = NULL;
|
||||
|
@ -3197,7 +3211,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
{
|
||||
if ((arrayType->mDimensions == 1) && (arrayType->mParams.size() != 0))
|
||||
{
|
||||
int rawElemHash = Hash(arrayType->mElementType, ctx);
|
||||
int rawElemHash = Hash(arrayType->mElementType, ctx, BfHashFlag_None, hashSeed);
|
||||
int elemHash = rawElemHash ^ HASH_SIZED_ARRAY;
|
||||
int hashVal = (elemHash << 5) - elemHash;
|
||||
|
||||
|
@ -3221,7 +3235,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
BfTypedValue typedVal = constResolver.Resolve(sizeExpr, NULL, BfConstResolveFlag_ArrayInitSize);
|
||||
if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
|
||||
{
|
||||
int elemHash = Hash(typedVal.mType, ctx);
|
||||
int elemHash = Hash(typedVal.mType, ctx, BfHashFlag_None, hashSeed);
|
||||
hashVal = ((hashVal ^ elemHash) << 5) - hashVal;
|
||||
return hashVal;
|
||||
}
|
||||
|
@ -3280,13 +3294,13 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
}
|
||||
}
|
||||
|
||||
int elemHash = Hash(arrayType->mElementType, ctx) ^ (arrayType->mDimensions << 8);
|
||||
int elemHash = Hash(arrayType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ (arrayType->mDimensions << 8);
|
||||
return (elemHash << 5) - elemHash;
|
||||
}
|
||||
}
|
||||
else if (auto pointerType = BfNodeDynCastExact<BfPointerTypeRef>(typeRef))
|
||||
{
|
||||
int elemHash = Hash(pointerType->mElementType, ctx) ^ HASH_VAL_PTR;
|
||||
int elemHash = Hash(pointerType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ HASH_VAL_PTR;
|
||||
return (elemHash << 5) - elemHash;
|
||||
}
|
||||
else if (auto nullableType = BfNodeDynCastExact<BfNullableTypeRef>(typeRef))
|
||||
|
@ -3294,8 +3308,8 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
if (ctx->mRootTypeRef == typeRef)
|
||||
ctx->mRootTypeDef = ctx->mModule->mCompiler->mNullableTypeDef;
|
||||
|
||||
int hashVal = ctx->mModule->mCompiler->mNullableTypeDef->mHash;
|
||||
hashVal = ((hashVal ^ (Hash(nullableType->mElementType, ctx))) << 5) - hashVal;
|
||||
int hashVal = ctx->mModule->mCompiler->mNullableTypeDef->mHash;
|
||||
hashVal = HASH_MIX(hashVal, Hash(nullableType->mElementType, ctx, BfHashFlag_None, hashSeed + 1));
|
||||
return hashVal;
|
||||
}
|
||||
else if (auto refType = BfNodeDynCastExact<BfRefTypeRef>(typeRef))
|
||||
|
@ -3312,7 +3326,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
else if (refType->mRefToken->GetToken() == BfToken_Mut)
|
||||
refKind = BfRefType::RefKind_Mut;
|
||||
|
||||
int elemHash = Hash(refType->mElementType, ctx) ^ (HASH_VAL_REF + (int)refKind);
|
||||
int elemHash = Hash(refType->mElementType, ctx, BfHashFlag_None, hashSeed) ^ (HASH_VAL_REF + (int)refKind);
|
||||
return (elemHash << 5) - elemHash;
|
||||
}
|
||||
else
|
||||
|
@ -3356,7 +3370,9 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
ctx->mFailed = true;
|
||||
return 0;
|
||||
}
|
||||
return Hash(resolvedType, ctx);
|
||||
int hashVal = Hash(resolvedType, ctx, BfHashFlag_None, hashSeed);
|
||||
hashSeed = 0;
|
||||
return hashVal;
|
||||
}
|
||||
else if (auto varType = BfNodeDynCastExact<BfVarTypeReference>(typeRef))
|
||||
{
|
||||
|
@ -3379,26 +3395,26 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
if (ctx->mRootTypeRef != retTypeTypeRef)
|
||||
{
|
||||
auto type = ctx->mModule->ResolveTypeRef(retTypeTypeRef, BfPopulateType_Identity, ctx->mResolveFlags);
|
||||
return Hash(type, ctx, flags);
|
||||
return Hash(type, ctx, flags, hashSeed);
|
||||
}
|
||||
|
||||
int elemHash = Hash(retTypeTypeRef->mElementType, ctx) ^ HASH_MODTYPE + retTypeTypeRef->mRetTypeToken->mToken;
|
||||
int elemHash = Hash(retTypeTypeRef->mElementType, ctx, BfHashFlag_None, hashSeed) ^ HASH_MODTYPE + retTypeTypeRef->mRetTypeToken->mToken;
|
||||
return (elemHash << 5) - elemHash;
|
||||
}
|
||||
else if (auto resolvedTypeRef = BfNodeDynCastExact<BfResolvedTypeReference>(typeRef))
|
||||
{
|
||||
return Hash(resolvedTypeRef->mType, ctx);
|
||||
return Hash(resolvedTypeRef->mType, ctx, BfHashFlag_None, hashSeed);
|
||||
}
|
||||
else if (auto constTypeRef = BfNodeDynCastExact<BfConstTypeRef>(typeRef))
|
||||
{
|
||||
// We purposely don't mix in a HASH_CONSTTYPE because there's no such thing as a const type in Beef, so we just strip it
|
||||
return Hash(constTypeRef->mElementType, ctx, flags);
|
||||
return Hash(constTypeRef->mElementType, ctx, flags, hashSeed);
|
||||
}
|
||||
else if (auto delegateTypeRef = BfNodeDynCastExact<BfDelegateTypeRef>(typeRef))
|
||||
{
|
||||
int hashVal = HASH_DELEGATE;
|
||||
if (delegateTypeRef->mReturnType != NULL)
|
||||
hashVal = ((hashVal ^ (Hash(delegateTypeRef->mReturnType, ctx, BfHashFlag_AllowRef))) << 5) - hashVal;
|
||||
hashVal = ((hashVal ^ (Hash(delegateTypeRef->mReturnType, ctx, BfHashFlag_AllowRef, hashSeed))) << 5) - hashVal;
|
||||
else
|
||||
ctx->mFailed = true;
|
||||
|
||||
|
@ -3431,7 +3447,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
}
|
||||
}
|
||||
|
||||
hashVal = ((hashVal ^ (Hash(fieldType, ctx, (BfHashFlags)(BfHashFlag_AllowRef)))) << 5) - hashVal;
|
||||
hashVal = ((hashVal ^ (Hash(fieldType, ctx, (BfHashFlags)(BfHashFlag_AllowRef), hashSeed))) << 5) - hashVal;
|
||||
hashVal = ((hashVal ^ (HashNode(param->mNameNode))) << 5) - hashVal;
|
||||
isFirstParam = true;
|
||||
}
|
||||
|
@ -3508,7 +3524,9 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
return 0;
|
||||
}
|
||||
|
||||
return Hash(cachedResolvedType, ctx, flags);
|
||||
int hashVal = Hash(cachedResolvedType, ctx, flags, hashSeed);
|
||||
hashSeed = 0;
|
||||
return hashVal;
|
||||
}
|
||||
else if (auto constExprTypeRef = BfNodeDynCastExact<BfConstExprTypeRef>(typeRef))
|
||||
{
|
||||
|
@ -3518,7 +3536,11 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
{
|
||||
result = EvaluateToVariant(ctx, constExprTypeRef->mConstExpr, resultType);
|
||||
if ((resultType != NULL) && (resultType->IsGenericParam()))
|
||||
return Hash(resultType, ctx);
|
||||
{
|
||||
int hashVal = Hash(resultType, ctx, BfHashFlag_None, hashSeed);
|
||||
hashSeed = 0;
|
||||
return hashVal;
|
||||
}
|
||||
}
|
||||
|
||||
if (resultType == NULL)
|
||||
|
@ -3528,7 +3550,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
}
|
||||
|
||||
auto hashVal = ((int)result.mTypeCode << 17) ^ (result.mInt32 << 3) ^ HASH_CONSTTYPE;
|
||||
hashVal = ((hashVal ^ (Hash(resultType, ctx, BfHashFlag_AllowRef))) << 5) - hashVal;
|
||||
hashVal = ((hashVal ^ (Hash(resultType, ctx, BfHashFlag_AllowRef, hashSeed))) << 5) - hashVal;
|
||||
return hashVal;
|
||||
}
|
||||
else if (auto dotTypeRef = BfNodeDynCastExact<BfDotTypeReference>(typeRef))
|
||||
|
@ -3544,6 +3566,14 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
|
|||
return 0;
|
||||
}
|
||||
|
||||
int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags, int hashSeed)
|
||||
{
|
||||
int hashVal = DoHash(typeRef, ctx, flags, hashSeed);
|
||||
if (hashSeed == 0)
|
||||
return hashVal;
|
||||
return HASH_MIX(hashVal, hashSeed);
|
||||
}
|
||||
|
||||
// These types can be from different contexts ("foreign" types) so we can't just compare ptrs
|
||||
bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx)
|
||||
{
|
||||
|
|
|
@ -501,6 +501,7 @@ public:
|
|||
virtual bool HasBeenReferenced() { return mDefineState != BfTypeDefineState_Undefined; }
|
||||
virtual bool HasTypeFailed() { return false; }
|
||||
virtual bool IsDataIncomplete() { return mDefineState == BfTypeDefineState_Undefined; }
|
||||
virtual bool IsFinishingType() { return false; }
|
||||
virtual bool IsIncomplete() { return mDefineState < BfTypeDefineState_Defined; }
|
||||
virtual bool IsDeleting() { return ((mRebuildFlags & (BfTypeRebuildFlag_Deleted | BfTypeRebuildFlag_DeleteQueued)) != 0); }
|
||||
virtual bool IsDeclared() { return mDefineState >= BfTypeDefineState_Declared; }
|
||||
|
@ -1774,6 +1775,7 @@ public:
|
|||
bool mInitializedGenericParams;
|
||||
bool mFinishedGenericParams;
|
||||
Array<BfProject*> mProjectsReferenced; // Generic methods that only refer to these projects don't need a specialized extension
|
||||
int32 mMaxGenericDepth;
|
||||
|
||||
public:
|
||||
BfGenericTypeInfo()
|
||||
|
@ -1785,6 +1787,7 @@ public:
|
|||
mValidatedGenericConstraints = false;
|
||||
mInitializedGenericParams = false;
|
||||
mFinishedGenericParams = false;
|
||||
mMaxGenericDepth = -1;
|
||||
}
|
||||
|
||||
~BfGenericTypeInfo();
|
||||
|
@ -1955,6 +1958,7 @@ public:
|
|||
virtual bool IsReified() override { return mIsReified; }
|
||||
virtual bool NeedsExplicitAlignment() override { return !IsSizeAligned() || mIsPacked; }
|
||||
virtual bool IsDataIncomplete() override { return ((mTypeIncomplete) || (mBaseTypeMayBeIncomplete)) && (!mNeedsMethodProcessing); }
|
||||
virtual bool IsFinishingType() override { return mIsFinishingType; }
|
||||
virtual bool IsIncomplete() override { return (mTypeIncomplete) || (mBaseTypeMayBeIncomplete); }
|
||||
virtual bool IsSplattable() override { BF_ASSERT((mInstSize >= 0) || (!IsComposite())); return mIsSplattable; }
|
||||
virtual int GetSplatCount() override;
|
||||
|
@ -2525,10 +2529,12 @@ public:
|
|||
static BfVariant EvaluateToVariant(LookupContext* ctx, BfExpression* expr, BfType*& outType);
|
||||
static bool GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* lhsTypeGenericArguments, BfTypeReference* rhs, LookupContext* ctx, int& genericParamOffset);
|
||||
static bool GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* typeGenericArguments, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx);
|
||||
static void HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hash);
|
||||
static int Hash(BfType* type, LookupContext* ctx, bool allowRef = false);
|
||||
static int DirectHash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags = BfHashFlag_None);
|
||||
static int Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags = BfHashFlag_None);
|
||||
static void HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hash, int hashSeed);
|
||||
static int DoHash(BfType* type, LookupContext* ctx, bool allowRef, int hashSeed);
|
||||
static int Hash(BfType* type, LookupContext* ctx, bool allowRef = false, int hashSeed = 0);
|
||||
static int DirectHash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags = BfHashFlag_None, int hashSeed = 0);
|
||||
static int DoHash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags, int& hashSeed);
|
||||
static int Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags = BfHashFlag_None, int hashSeed = 0);
|
||||
static bool Equals(BfType* lhs, BfType* rhs, LookupContext* ctx);
|
||||
static bool Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* ctx);
|
||||
static bool Equals(BfType* lhs, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "BfSourceClassifier.h"
|
||||
#include "BfParser.h"
|
||||
#include "BeefySysLib/util/BeefPerf.h"
|
||||
|
||||
USING_NS_BF;
|
||||
|
||||
|
@ -421,14 +422,22 @@ void BfSourceClassifier::Visit(BfTokenNode* tokenNode)
|
|||
|
||||
void BfSourceClassifier::Visit(BfInvocationExpression* invocationExpr)
|
||||
{
|
||||
BfElementVisitor::Visit(invocationExpr);
|
||||
//BfElementVisitor::Visit(invocationExpr);
|
||||
Visit(invocationExpr->ToBase());
|
||||
|
||||
//BP_ZONE("BfSourceClassifier BfInvocationExpression");
|
||||
|
||||
BfAstNode* target = invocationExpr->mTarget;
|
||||
if (target == NULL)
|
||||
return;
|
||||
|
||||
|
||||
VisitChild(invocationExpr->mOpenParen);
|
||||
VisitChild(invocationExpr->mCloseParen);
|
||||
VisitChild(invocationExpr->mGenericArgs);
|
||||
|
||||
if (auto scopedTarget = BfNodeDynCast<BfScopedInvocationTarget>(target))
|
||||
{
|
||||
VisitChild(target);
|
||||
target = scopedTarget->mTarget;
|
||||
VisitChild(scopedTarget->mScopeName);
|
||||
}
|
||||
|
@ -438,25 +447,33 @@ void BfSourceClassifier::Visit(BfInvocationExpression* invocationExpr)
|
|||
{
|
||||
VisitChild(qualifiedName->mLeft);
|
||||
VisitChild(qualifiedName->mDot);
|
||||
VisitChild(qualifiedName->mRight);
|
||||
identifier = qualifiedName->mRight;
|
||||
}
|
||||
else if ((identifier = BfNodeDynCast<BfIdentifierNode>(target)))
|
||||
{
|
||||
VisitChild(target);
|
||||
// Leave as BfAttributedIdentifierNode if that's the case
|
||||
identifier = target;
|
||||
identifier = target;
|
||||
}
|
||||
else if (auto qualifiedName = BfNodeDynCast<BfQualifiedNameNode>(target))
|
||||
{
|
||||
VisitChild(qualifiedName->mLeft);
|
||||
VisitChild(qualifiedName->mDot);
|
||||
VisitChild(qualifiedName->mRight);
|
||||
identifier = qualifiedName->mRight;
|
||||
}
|
||||
else if (auto memberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(target))
|
||||
{
|
||||
VisitChild(memberRefExpr->mTarget);
|
||||
VisitChild(memberRefExpr->mDotToken);
|
||||
VisitChild(memberRefExpr->mMemberName);
|
||||
identifier = memberRefExpr->mMemberName;
|
||||
}
|
||||
else
|
||||
{
|
||||
VisitChild(target);
|
||||
}
|
||||
|
||||
if (identifier != NULL)
|
||||
{
|
||||
|
@ -469,20 +486,25 @@ void BfSourceClassifier::Visit(BfInvocationExpression* invocationExpr)
|
|||
if (identifier != NULL)
|
||||
SetElementType(identifier, BfSourceElementType_Method);
|
||||
}
|
||||
|
||||
for (auto& val : invocationExpr->mArguments)
|
||||
VisitChild(val);
|
||||
for (auto& val : invocationExpr->mCommas)
|
||||
VisitChild(val);
|
||||
}
|
||||
|
||||
void BfSourceClassifier::Visit(BfIndexerExpression* indexerExpr)
|
||||
{
|
||||
BfElementVisitor::Visit(indexerExpr);
|
||||
//BfElementVisitor::Visit(indexerExpr);
|
||||
Visit(indexerExpr->ToBase());
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
for (auto& val : indexerExpr->mArguments)
|
||||
VisitChild(val);
|
||||
for (auto& val : indexerExpr->mCommas)
|
||||
VisitChild(val);
|
||||
VisitChild(indexerExpr->mCloseBracket);
|
||||
}
|
||||
|
||||
|
@ -523,6 +545,8 @@ void BfSourceClassifier::Visit(BfMethodDeclaration* methodDeclaration)
|
|||
if (!IsInterestedInMember(methodDeclaration))
|
||||
return;
|
||||
|
||||
//BP_ZONE("BfSourceClassifier BfMethodDeclaration");
|
||||
|
||||
SetAndRestoreValue<BfAstNode*> prevMember(mCurMember, methodDeclaration);
|
||||
|
||||
BfElementVisitor::Visit(methodDeclaration);
|
||||
|
|
|
@ -1654,7 +1654,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
|
|||
if (isConst)
|
||||
{
|
||||
BfConstResolver constResolver(this);
|
||||
initValue = constResolver.Resolve(varDecl->mInitializer, resolvedType, BfConstResolveFlag_RemapFromStringId);
|
||||
initValue = constResolver.Resolve(varDecl->mInitializer, resolvedType, BfConstResolveFlag_ActualizeValues);
|
||||
if (!initValue)
|
||||
initValue = GetDefaultTypedValue(resolvedType);
|
||||
}
|
||||
|
@ -3934,15 +3934,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt)
|
|||
bool allowProtected = allowPrivate || TypeIsSubTypeOf(mCurTypeInstance, checkTypeInst);
|
||||
while (checkTypeInst != NULL)
|
||||
{
|
||||
auto checkTypeDef = checkTypeInst->mTypeDef;
|
||||
|
||||
checkTypeDef->PopulateMemberSets();
|
||||
BfMemberSetEntry* entry = NULL;
|
||||
BfMethodDef* dtorMethodDef = NULL;
|
||||
checkTypeDef->mMethodSet.TryGetWith(String("~this"), &entry);
|
||||
if (entry != NULL)
|
||||
dtorMethodDef = (BfMethodDef*)entry->mMemberDef;
|
||||
|
||||
auto dtorMethodDef = checkTypeInst->mTypeDef->GetMethodByName("~this");
|
||||
if (dtorMethodDef)
|
||||
{
|
||||
if (!CheckProtection(dtorMethodDef->mProtection, checkTypeInst->mTypeDef, allowProtected, allowPrivate))
|
||||
|
@ -6734,7 +6726,13 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
|
|||
|
||||
if ((scope == mCurMethodState->mCurScope) && (scope->mCloseNode == NULL))
|
||||
{
|
||||
Warn(0, "This defer will immediately execute. Consider specifying a wider scope target such as 'defer::'", deferStmt->mDeferToken);
|
||||
auto parser = deferStmt->GetParser();
|
||||
if ((parser != NULL) && (parser->mFileName.Contains('|')))
|
||||
{
|
||||
// Is emitted
|
||||
}
|
||||
else
|
||||
Warn(0, "This defer will immediately execute. Consider specifying a wider scope target such as 'defer::'", deferStmt->mDeferToken);
|
||||
}
|
||||
|
||||
if (auto block = BfNodeDynCast<BfBlock>(deferStmt->mTargetNode))
|
||||
|
|
|
@ -833,12 +833,26 @@ int BfTypeDef::GetSelfGenericParamCount()
|
|||
|
||||
BfMethodDef* BfTypeDef::GetMethodByName(const StringImpl& name, int paramCount)
|
||||
{
|
||||
for (auto method : mMethods)
|
||||
{
|
||||
if ((name == method->mName) && ((paramCount == -1) || (paramCount == (int)method->mParams.size())))
|
||||
return method;
|
||||
PopulateMemberSets();
|
||||
BfMemberSetEntry* entry = NULL;
|
||||
if (!mMethodSet.TryGetWith(name, &entry))
|
||||
return NULL;
|
||||
|
||||
BfMethodDef* bestMethodDef = NULL;
|
||||
auto methodDef = (BfMethodDef*)entry->mMemberDef;
|
||||
while (methodDef != NULL)
|
||||
{
|
||||
if (((paramCount == -1) || (paramCount == (int)methodDef->mParams.size())))
|
||||
{
|
||||
if ((bestMethodDef == NULL) ||
|
||||
((bestMethodDef->mDeclaringType->IsExtension()) && (!methodDef->mDeclaringType->IsExtension())))
|
||||
bestMethodDef = methodDef;
|
||||
}
|
||||
|
||||
methodDef = methodDef->mNextWithSameName;
|
||||
}
|
||||
return NULL;
|
||||
|
||||
return bestMethodDef;
|
||||
}
|
||||
|
||||
BfFieldDef* BfTypeDef::GetFieldByName(const StringImpl& name)
|
||||
|
@ -1810,7 +1824,7 @@ BfSystem::BfSystem()
|
|||
if (gPerfManager == NULL)
|
||||
gPerfManager = new PerfManager();
|
||||
//gPerfManager->StartRecording();
|
||||
|
||||
|
||||
mAtomUpdateIdx = 0;
|
||||
mAtomCreateIdx = 0;
|
||||
mTypeMapVersion = 1;
|
||||
|
@ -2586,6 +2600,13 @@ void BfSystem::RemoveTypeDef(BfTypeDef* typeDef)
|
|||
mTypeDefs.Remove(typeDef);
|
||||
AutoCrit autoCrit(mDataLock);
|
||||
|
||||
if (typeDef->mOuterType != NULL)
|
||||
{
|
||||
// We are in the outer type's mNestedTypes list
|
||||
BfLogSys(this, "Setting mForceUseNextRevision on outer type %p from %p\n", typeDef->mOuterType, typeDef);
|
||||
typeDef->mOuterType->mForceUseNextRevision = true;
|
||||
}
|
||||
|
||||
// This will get properly handled in UntrackName when we process the mTypeDefDeleteQueue, but this
|
||||
// mAtomUpdateIdx increment will trigger lookup changes in BfContext::VerifyTypeLookups
|
||||
if (typeDef->mName != mEmptyAtom)
|
||||
|
@ -2797,6 +2818,7 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef)
|
|||
typeDef->mNextRevision = NULL;
|
||||
|
||||
typeDef->mDefState = BfTypeDef::DefState_Defined;
|
||||
typeDef->mForceUseNextRevision = false;
|
||||
|
||||
VerifyTypeDef(typeDef);
|
||||
}
|
||||
|
|
|
@ -1006,6 +1006,7 @@ public:
|
|||
bool mIsNextRevision;
|
||||
bool mInDeleteQueue;
|
||||
bool mHasEmitMembers;
|
||||
bool mForceUseNextRevision;
|
||||
|
||||
public:
|
||||
BfTypeDef()
|
||||
|
@ -1048,6 +1049,7 @@ public:
|
|||
mIsNextRevision = false;
|
||||
mInDeleteQueue = false;
|
||||
mHasEmitMembers = false;
|
||||
mForceUseNextRevision = false;
|
||||
mDupDetectedRevision = -1;
|
||||
mNestDepth = 0;
|
||||
mOuterType = NULL;
|
||||
|
@ -1500,7 +1502,7 @@ public:
|
|||
Array<BfTypeOptions> mMergedTypeOptions;
|
||||
int mUpdateCnt;
|
||||
bool mWorkspaceConfigChanged;
|
||||
Val128 mWorkspaceConfigHash;
|
||||
Val128 mWorkspaceConfigHash;
|
||||
|
||||
Array<BfCompiler*> mCompilers;
|
||||
|
||||
|
|
|
@ -3809,7 +3809,7 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
|||
|
||||
BfIRValue CeContext::CreateAttribute(BfAstNode* targetSrc, BfModule* module, BfIRConstHolder* constHolder, BfCustomAttribute* customAttribute)
|
||||
{
|
||||
module->PopulateType(customAttribute->mType);
|
||||
module->mContext->mUnreifiedModule->PopulateType(customAttribute->mType);
|
||||
auto ceAttrAddr = CeMalloc(customAttribute->mType->mSize) - mMemory.mVals;
|
||||
BfIRValue ceAttrVal = module->mBfIRBuilder->CreateConstAggCE(module->mBfIRBuilder->MapType(customAttribute->mType, BfIRPopulateType_Identity), ceAttrAddr);
|
||||
BfTypedValue ceAttrTypedValue(ceAttrVal, customAttribute->mType);
|
||||
|
@ -4335,7 +4335,7 @@ static void CeSetAddrVal(void* ptr, addr_ce val, int32 ptrSize)
|
|||
}
|
||||
|
||||
bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr, BfType*& returnType)
|
||||
{
|
||||
{
|
||||
auto ceModule = mCeMachine->mCeModule;
|
||||
CeFunction* ceFunction = startFunction;
|
||||
returnType = startFunction->mMethodInstance->mReturnType;
|
||||
|
@ -5408,6 +5408,15 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
mCeMachine->PrepareFunction(callEntry.mFunction, NULL);
|
||||
}
|
||||
|
||||
if (callEntry.mFunction->mMethodInstance != NULL)
|
||||
{
|
||||
if (callEntry.mFunction->mMethodInstance->GetOwner()->IsDeleting())
|
||||
{
|
||||
_Fail("Calling method on deleted type");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
callEntry.mBindRevision = mCeMachine->mMethodBindRevision;
|
||||
}
|
||||
|
||||
|
@ -6255,6 +6264,9 @@ CeMachine::~CeMachine()
|
|||
|
||||
auto _RemoveFunctionInfo = [&](CeFunctionInfo* functionInfo)
|
||||
{
|
||||
if (functionInfo->mMethodInstance != NULL)
|
||||
functionInfo->mMethodInstance->mInCEMachine = false;
|
||||
|
||||
if (functionInfo->mCeFunction != NULL)
|
||||
{
|
||||
// We don't need to actually unmap it at this point
|
||||
|
@ -6411,8 +6423,21 @@ CeErrorKind CeMachine::WriteConstant(CeConstStructData& data, BeConstant* constV
|
|||
if (globalVar->mName.StartsWith("__bfStrObj"))
|
||||
{
|
||||
int stringId = atoi(globalVar->mName.c_str() + 10);
|
||||
addr_ce stringAddr = ceContext->GetString(stringId);
|
||||
|
||||
addr_ce stringAddr;
|
||||
if (data.mQueueFixups)
|
||||
{
|
||||
stringAddr = 0;
|
||||
CeConstStructFixup fixup;
|
||||
fixup.mKind = CeConstStructFixup::Kind_StringPtr;
|
||||
fixup.mValue = stringId;
|
||||
fixup.mOffset = (int)data.mData.mSize;
|
||||
data.mFixups.Add(fixup);
|
||||
}
|
||||
else
|
||||
{
|
||||
stringAddr = ceContext->GetString(stringId);
|
||||
}
|
||||
auto ptr = data.mData.GrowUninitialized(ceModule->mSystem->mPtrSize);
|
||||
int64 addr64 = stringAddr;
|
||||
memcpy(ptr, &addr64, ceModule->mSystem->mPtrSize);
|
||||
|
@ -6932,10 +6957,9 @@ CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance, BfIRValue f
|
|||
ceFunction->mCeMachine = this;
|
||||
ceFunction->mIsVarReturn = methodInstance->mReturnType->IsVar();
|
||||
ceFunction->mCeFunctionInfo = ceFunctionInfo;
|
||||
ceFunction->mMethodInstance = methodInstance;
|
||||
|
||||
ceFunction->mMethodInstance = methodInstance;
|
||||
ceFunctionInfo->mMethodInstance = methodInstance;
|
||||
ceFunctionInfo->mCeFunction = ceFunction;
|
||||
ceFunctionInfo->mCeFunction = ceFunction;
|
||||
MapFunctionId(ceFunction);
|
||||
}
|
||||
|
||||
|
|
|
@ -120,6 +120,7 @@ enum DwEvalExpressionFlags : int16
|
|||
DwEvalExpressionFlag_MemoryWatch = 0x80,
|
||||
DwEvalExpressionFlag_Symbol = 0x100,
|
||||
DwEvalExpressionFlag_StepIntoCalls = 0x200,
|
||||
DwEvalExpressionFlag_RawStr = 0x400
|
||||
};
|
||||
|
||||
struct DwDisplayInfo
|
||||
|
|
|
@ -82,17 +82,14 @@ static size_t WriteMemoryCallback(void* contents, size_t size, size_t nmemb, voi
|
|||
void NetRequest::Cleanup()
|
||||
{
|
||||
if (mCURLMulti != NULL)
|
||||
{
|
||||
curl_multi_remove_handle(mCURLMulti, mCURL);
|
||||
}
|
||||
curl_multi_remove_handle(mCURLMulti, mCURL);
|
||||
if (mCURL != NULL)
|
||||
curl_easy_cleanup(mCURL);
|
||||
if (mCURLMulti != NULL)
|
||||
curl_multi_cleanup(mCURLMulti);
|
||||
|
||||
if (mCURL != NULL)
|
||||
curl_easy_cleanup(mCURL);
|
||||
|
||||
if (mCURLMulti != NULL)
|
||||
{
|
||||
curl_multi_cleanup(mCURLMulti);
|
||||
}
|
||||
mCURL = NULL;
|
||||
mCURLMulti = NULL;
|
||||
}
|
||||
|
||||
void NetRequest::DoTransfer()
|
||||
|
@ -105,65 +102,75 @@ void NetRequest::DoTransfer()
|
|||
// return;
|
||||
// }
|
||||
|
||||
BfLogDbg("NetManager starting get on %s\n", mURL.c_str());
|
||||
mNetManager->mDebugManager->OutputRawMessage(StrFormat("msgLo Getting '%s'\n", mURL.c_str()));
|
||||
|
||||
mOutTempPath = mOutPath + "__partial";
|
||||
|
||||
mCURLMulti = curl_multi_init();
|
||||
|
||||
mCURL = curl_easy_init();
|
||||
|
||||
if (mShowTracking)
|
||||
{
|
||||
mNetManager->mDebugManager->OutputRawMessage(StrFormat("symsrv Getting '%s'", mURL.c_str()));
|
||||
}
|
||||
|
||||
//OutputDebugStrF("Getting '%s'\n", mURL.c_str());
|
||||
|
||||
curl_easy_setopt(mCURL, CURLOPT_URL, mURL.c_str());
|
||||
curl_easy_setopt(mCURL, CURLOPT_WRITEDATA, (void*)this);
|
||||
curl_easy_setopt(mCURL, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
|
||||
curl_easy_setopt(mCURL, CURLOPT_XFERINFODATA, (void*)this);
|
||||
curl_easy_setopt(mCURL, CURLOPT_XFERINFOFUNCTION, TransferInfoCallback);
|
||||
curl_easy_setopt(mCURL, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
curl_easy_setopt(mCURL, CURLOPT_NOPROGRESS, 0L);
|
||||
curl_easy_setopt(mCURL, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); // Connects go slow without this
|
||||
//auto result = curl_easy_perform(mCURL);
|
||||
|
||||
CURLMcode mcode = curl_multi_add_handle(mCURLMulti, mCURL);
|
||||
if (mcode != CURLM_OK)
|
||||
long response_code = 0;
|
||||
for (int pass = 0; pass < 3; pass++)
|
||||
{
|
||||
mFailed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
int activeCount = 0;
|
||||
curl_multi_perform(mCURLMulti, &activeCount);
|
||||
if (activeCount == 0)
|
||||
break;
|
||||
BfLogDbg("NetManager starting get on %s Pass:%d\n", mURL.c_str(), pass);
|
||||
mNetManager->mDebugManager->OutputRawMessage(StrFormat("msgLo Getting '%s'\n", mURL.c_str()));
|
||||
|
||||
int waitRet = 0;
|
||||
curl_multi_wait(mCURLMulti, NULL, 0, 20, &waitRet);
|
||||
mOutTempPath = mOutPath + "__partial";
|
||||
|
||||
if (mCancelling)
|
||||
mCURLMulti = curl_multi_init();
|
||||
|
||||
mCURL = curl_easy_init();
|
||||
|
||||
if (mShowTracking)
|
||||
{
|
||||
mNetManager->mDebugManager->OutputRawMessage(StrFormat("symsrv Getting '%s'", mURL.c_str()));
|
||||
}
|
||||
|
||||
//OutputDebugStrF("Getting '%s'\n", mURL.c_str());
|
||||
|
||||
curl_easy_setopt(mCURL, CURLOPT_URL, mURL.c_str());
|
||||
curl_easy_setopt(mCURL, CURLOPT_WRITEDATA, (void*)this);
|
||||
curl_easy_setopt(mCURL, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
|
||||
curl_easy_setopt(mCURL, CURLOPT_XFERINFODATA, (void*)this);
|
||||
curl_easy_setopt(mCURL, CURLOPT_XFERINFOFUNCTION, TransferInfoCallback);
|
||||
curl_easy_setopt(mCURL, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
curl_easy_setopt(mCURL, CURLOPT_NOPROGRESS, 0L);
|
||||
curl_easy_setopt(mCURL, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); // Connects go slow without this
|
||||
//auto result = curl_easy_perform(mCURL);
|
||||
|
||||
CURLMcode mcode = curl_multi_add_handle(mCURLMulti, mCURL);
|
||||
if (mcode != CURLM_OK)
|
||||
{
|
||||
mFailed = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if (result != CURLE_OK)
|
||||
// {
|
||||
// mFailed = true;
|
||||
// return;
|
||||
// }
|
||||
while (true)
|
||||
{
|
||||
int activeCount = 0;
|
||||
curl_multi_perform(mCURLMulti, &activeCount);
|
||||
if (activeCount == 0)
|
||||
break;
|
||||
|
||||
int waitRet = 0;
|
||||
curl_multi_wait(mCURLMulti, NULL, 0, 20, &waitRet);
|
||||
|
||||
if (mCancelling)
|
||||
{
|
||||
mFailed = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if (result != CURLE_OK)
|
||||
// {
|
||||
// mFailed = true;
|
||||
// return;
|
||||
// }
|
||||
|
||||
long response_code = 0;
|
||||
curl_easy_getinfo(mCURL, CURLINFO_RESPONSE_CODE, &response_code);
|
||||
mNetManager->mDebugManager->OutputRawMessage(StrFormat("msgLo Result for '%s': %d\n", mURL.c_str(), response_code));
|
||||
response_code = 0;
|
||||
curl_easy_getinfo(mCURL, CURLINFO_RESPONSE_CODE, &response_code);
|
||||
mNetManager->mDebugManager->OutputRawMessage(StrFormat("msgLo Result for '%s': %d\n", mURL.c_str(), response_code));
|
||||
|
||||
if ((response_code == 0) || (response_code == 200) || (response_code == 404))
|
||||
break;
|
||||
|
||||
Cleanup();
|
||||
// Try again!
|
||||
}
|
||||
|
||||
if (response_code == 200)
|
||||
{
|
||||
|
|
|
@ -80,6 +80,21 @@ namespace Tests
|
|||
}
|
||||
}
|
||||
|
||||
[IFaceA("C", InitVal=345)]
|
||||
struct StructA
|
||||
{
|
||||
public int mA = 123;
|
||||
|
||||
[OnCompile(.TypeInit), Comptime]
|
||||
public static void Generate()
|
||||
{
|
||||
Compiler.EmitTypeBody(typeof(Self), """
|
||||
public int32 mB = 234;
|
||||
public int32 GetValB() => mB;
|
||||
""");
|
||||
}
|
||||
}
|
||||
|
||||
enum MethodAErr
|
||||
{
|
||||
ErrorA,
|
||||
|
@ -168,6 +183,13 @@ namespace Tests
|
|||
Test.Assert(ca.mC == 345);
|
||||
Test.Assert(ca.GetValC() == 345);
|
||||
|
||||
StructA sa = .();
|
||||
Test.Assert(sa.mA == 123);
|
||||
Test.Assert(sa.mB == 234);
|
||||
Test.Assert(sa.GetValB() == 234);
|
||||
Test.Assert(sa.mC == 345);
|
||||
Test.Assert(sa.GetValC() == 345);
|
||||
|
||||
Compiler.Mixin("int val = 99;");
|
||||
Test.Assert(val == 99);
|
||||
|
||||
|
|
|
@ -160,6 +160,32 @@ namespace Tests
|
|||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
class ClassF
|
||||
{
|
||||
public static int sVal = 3;
|
||||
|
||||
public int mF0 = 1 ~
|
||||
{
|
||||
sVal += 40;
|
||||
};
|
||||
}
|
||||
|
||||
extension ClassF
|
||||
{
|
||||
public int mF1 = 2 ~
|
||||
{
|
||||
sVal += 500;
|
||||
};
|
||||
}
|
||||
|
||||
class ClassG : ClassF
|
||||
{
|
||||
public int mG0 = 3 ~
|
||||
{
|
||||
sVal += 6000;
|
||||
};
|
||||
}
|
||||
|
||||
extension TClassA<T> where T : IGetExVal
|
||||
{
|
||||
|
@ -226,6 +252,26 @@ namespace Tests
|
|||
ClassE ce = scope .();
|
||||
Test.Assert(ce.mD == 1);
|
||||
Test.Assert(ce.mE == 1);
|
||||
|
||||
///
|
||||
{
|
||||
ClassF cf = scope .();
|
||||
}
|
||||
Test.Assert(ClassF.sVal == 543);
|
||||
///
|
||||
{
|
||||
ClassF.sVal = 3;
|
||||
ClassG cg = scope .();
|
||||
}
|
||||
Test.Assert(ClassF.sVal == 6543);
|
||||
ClassF.sVal = 3;
|
||||
Object obj = new ClassF();
|
||||
delete obj;
|
||||
Test.Assert(ClassF.sVal == 543);
|
||||
ClassF.sVal = 3;
|
||||
obj = new ClassG();
|
||||
delete obj;
|
||||
Test.Assert(ClassF.sVal == 6543);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
@ -95,6 +95,16 @@ namespace Tests
|
|||
}
|
||||
}
|
||||
|
||||
class IFaceA<T0, T1> where T0 : Dictionary<T1, int> where T1 : IHashable
|
||||
{
|
||||
Dictionary<T1, int> mDict;
|
||||
}
|
||||
|
||||
public static void MethodA<T0, T1>() where T0 : Dictionary<T1, int> where T1 : IHashable
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestBasics()
|
||||
{
|
||||
|
|
|
@ -239,6 +239,32 @@ namespace Tests
|
|||
switch (methodIdx)
|
||||
{
|
||||
case 0:
|
||||
Test.Assert(methodInfo.Name == "__BfCtor");
|
||||
Test.Assert(methodInfo.IsConstructor);
|
||||
case 1:
|
||||
Test.Assert(methodInfo.Name == "__BfStaticCtor");
|
||||
Test.Assert(methodInfo.IsConstructor);
|
||||
case 2:
|
||||
Test.Assert(methodInfo.Name == "GetA");
|
||||
var result = methodInfo.Invoke(ca, 123).Get();
|
||||
Test.Assert(result.Get<int>() == 1123);
|
||||
result.Dispose();
|
||||
result = methodInfo.Invoke(ca2, 123).Get();
|
||||
Test.Assert(result.Get<int>() == 2123);
|
||||
result.Dispose();
|
||||
result = methodInfo.Invoke(.Create(ca2), .Create(123)).Get();
|
||||
Test.Assert(result.Get<int>() == 2123);
|
||||
result.Dispose();
|
||||
case 3:
|
||||
Test.Assert(methodInfo.Name == "MemberMethodA");
|
||||
var result = methodInfo.Invoke(ca, 100, (int32)20, 3.0f).Get();
|
||||
Test.Assert(result.Get<float>() == 123);
|
||||
result.Dispose();
|
||||
|
||||
result = methodInfo.Invoke(.Create(ca), .Create(100), .Create((int32)20), .Create(3.0f)).Get();
|
||||
Test.Assert(result.Get<float>() == 123);
|
||||
result.Dispose();
|
||||
case 4:
|
||||
StructA sa = .() { mA = 1, mB = 2 };
|
||||
|
||||
Test.Assert(methodInfo.Name == "StaticMethodA");
|
||||
|
@ -291,7 +317,7 @@ namespace Tests
|
|||
let attrC = methodInfo.GetCustomAttribute<AttrCAttribute>().Get();
|
||||
Test.Assert(attrC.mA == 71);
|
||||
Test.Assert(attrC.mB == 72);
|
||||
case 1:
|
||||
case 5:
|
||||
Test.Assert(methodInfo.Name == "StaticMethodB");
|
||||
|
||||
var fieldA = typeInfo.GetField("mA").Value;
|
||||
|
@ -337,33 +363,6 @@ namespace Tests
|
|||
res.Dispose();
|
||||
fieldSAV.Dispose();
|
||||
fieldSStrV.Dispose();
|
||||
|
||||
case 2:
|
||||
Test.Assert(methodInfo.Name == "MemberMethodA");
|
||||
var result = methodInfo.Invoke(ca, 100, (int32)20, 3.0f).Get();
|
||||
Test.Assert(result.Get<float>() == 123);
|
||||
result.Dispose();
|
||||
|
||||
result = methodInfo.Invoke(.Create(ca), .Create(100), .Create((int32)20), .Create(3.0f)).Get();
|
||||
Test.Assert(result.Get<float>() == 123);
|
||||
result.Dispose();
|
||||
case 3:
|
||||
Test.Assert(methodInfo.Name == "GetA");
|
||||
var result = methodInfo.Invoke(ca, 123).Get();
|
||||
Test.Assert(result.Get<int>() == 1123);
|
||||
result.Dispose();
|
||||
result = methodInfo.Invoke(ca2, 123).Get();
|
||||
Test.Assert(result.Get<int>() == 2123);
|
||||
result.Dispose();
|
||||
result = methodInfo.Invoke(.Create(ca2), .Create(123)).Get();
|
||||
Test.Assert(result.Get<int>() == 2123);
|
||||
result.Dispose();
|
||||
case 4:
|
||||
Test.Assert(methodInfo.Name == "__BfStaticCtor");
|
||||
Test.Assert(methodInfo.IsConstructor);
|
||||
case 5:
|
||||
Test.Assert(methodInfo.Name == "__BfCtor");
|
||||
Test.Assert(methodInfo.IsConstructor);
|
||||
case 6:
|
||||
Test.FatalError(); // Shouldn't have any more
|
||||
}
|
||||
|
@ -445,6 +444,8 @@ namespace Tests
|
|||
switch (methodIdx)
|
||||
{
|
||||
case 0:
|
||||
Test.Assert(methodInfo.Name == "__BfCtor");
|
||||
case 1:
|
||||
Test.Assert(methodInfo.Name == "GetA");
|
||||
|
||||
var result = methodInfo.Invoke(sa, 34).Get();
|
||||
|
@ -464,7 +465,7 @@ namespace Tests
|
|||
result = methodInfo.Invoke(.Create(&sa), .Create(34));
|
||||
Test.Assert(result.Get<int32>() == 1234);
|
||||
result.Dispose();
|
||||
case 1:
|
||||
case 2:
|
||||
Test.Assert(methodInfo.Name == "GetB");
|
||||
|
||||
var result = methodInfo.Invoke(sa, 34).Get();
|
||||
|
@ -489,16 +490,15 @@ namespace Tests
|
|||
Test.Assert(sa.mB == 91);
|
||||
result.Dispose();
|
||||
|
||||
case 2:
|
||||
Test.Assert(methodInfo.Name == "MethodA0");
|
||||
case 3:
|
||||
Test.Assert(methodInfo.Name == "MethodA1");
|
||||
Test.Assert(methodInfo.Name == "MethodA0");
|
||||
case 4:
|
||||
Test.Assert(methodInfo.Name == "__BfCtor");
|
||||
Test.Assert(methodInfo.Name == "MethodA1");
|
||||
case 5:
|
||||
Test.Assert(methodInfo.Name == "__Equals");
|
||||
case 6:
|
||||
Test.Assert(methodInfo.Name == "__StrictEquals");
|
||||
|
||||
default:
|
||||
Test.FatalError(); // Shouldn't have any more
|
||||
}
|
||||
|
|
|
@ -9504,6 +9504,11 @@ String WinDebugger::Evaluate(const StringImpl& expr, DwFormatInfo formatInfo, in
|
|||
expressionFlags = (DwEvalExpressionFlags)(expressionFlags & ~DwEvalExpressionFlag_AllowCalls);
|
||||
}
|
||||
|
||||
if ((expressionFlags & DwEvalExpressionFlag_RawStr) != 0)
|
||||
{
|
||||
formatInfo.mRawString = true;
|
||||
}
|
||||
|
||||
auto dbgModule = GetCallStackDbgModule(callStackIdx);
|
||||
auto dbgSubprogram = GetCallStackSubprogram(callStackIdx);
|
||||
DbgCompileUnit* dbgCompileUnit = NULL;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue