1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 03:28:20 +02:00

Lost changes

This commit is contained in:
Brian Fiete 2021-02-25 10:14:22 -08:00
parent e6c4a95ccd
commit 8e9d7ed4c4
56 changed files with 1579 additions and 794 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,3 +1,8 @@
#define INITKNOWNFOLDERS
#include <guiddef.h>
#include <KnownFolders.h>
#undef INITKNOWNFOLDERS
#pragma warning(disable:4065)
#pragma warning(disable:4996)

View file

@ -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;
// 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();
checkEntry = nextEntry;
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;
}
}
}

View file

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

View file

@ -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 ");
}
@ -1063,16 +1053,7 @@ 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))
@ -1227,21 +1221,8 @@ namespace IDE
}
}
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;
}
}
}

View file

@ -96,7 +96,8 @@ namespace IDE.Debugger
MemoryAddress = 0x40,
MemoryWatch = 0x80,
Symbol = 0x100,
StepIntoCall = 0x200
StepIntoCall = 0x200,
RawStr = 0x400,
}
[Reflect]

View file

@ -436,6 +436,12 @@ namespace IDE
}
}
public class ScriptCmd : ExecutionCmd
{
public String mCmd ~ delete _;
public String mPath ~ delete _;
}
public enum ArgsFileKind
{
None,
@ -7448,82 +7454,102 @@ namespace IDE
}
}
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);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -691,6 +691,8 @@ void BeIRCodeGen::Read(BeValue*& beValue)
CMD_PARAM(String, name);
CMD_PARAM(bool, isTLS);
BF_ASSERT(varType != NULL);
auto globalVariable = mBeModule->mGlobalVariables.Alloc();
globalVariable->mModule = mBeModule;
globalVariable->mType = varType;
@ -1907,6 +1909,8 @@ void BeIRCodeGen::HandleNextCmd()
CMD_PARAM(bool, isTLS);
CMD_PARAM(BeConstant*, initializer);
BF_ASSERT(varType != NULL);
auto globalVariable = mBeModule->mGlobalVariables.Alloc();
globalVariable->mModule = mBeModule;
globalVariable->mType = varType;

View file

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

View file

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

View file

@ -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;
@ -407,7 +407,6 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
mNoExtensionAttributeTypeDef = NULL;
mCheckedAttributeTypeDef = NULL;
mUncheckedAttributeTypeDef = NULL;
mFunctionTypeDef = NULL;
mGCTypeDef = NULL;
mGenericIEnumerableTypeDef = NULL;
mGenericIEnumeratorTypeDef = NULL;
@ -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;
@ -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");
@ -6663,7 +6675,6 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
mCheckedAttributeTypeDef = _GetRequiredType("System.CheckedAttribute");
mUncheckedAttributeTypeDef = _GetRequiredType("System.UncheckedAttribute");
mResultTypeDef = _GetRequiredType("System.Result", 1);
mFunctionTypeDef = _GetRequiredType("System.Function");
mGCTypeDef = _GetRequiredType("System.GC");
mGenericIEnumerableTypeDef = _GetRequiredType("System.Collections.IEnumerable", 1);
mGenericIEnumeratorTypeDef = _GetRequiredType("System.Collections.IEnumerator", 1);
@ -6722,22 +6733,18 @@ 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);
if (!mIsResolveOnly)
{
HashSet<BfModule*> foundVDataModuleSet;
@ -6812,18 +6819,13 @@ 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);
@ -6865,8 +6867,7 @@ 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))
{
@ -7099,12 +7100,11 @@ 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)
{
@ -7251,8 +7251,6 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
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())
{

View file

@ -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,6 +353,7 @@ public:
BfTypeDef* mDbgRawAllocDataTypeDef;
BfTypeDef* mDeferredCallTypeDef;
BfTypeDef* mDelegateTypeDef;
BfTypeDef* mFunctionTypeDef;
BfTypeDef* mActionTypeDef;
BfTypeDef* mEnumTypeDef;
BfTypeDef* mStringTypeDef;
@ -359,7 +361,6 @@ public:
BfTypeDef* mTypeTypeDef;
BfTypeDef* mValueTypeTypeDef;
BfTypeDef* mResultTypeDef;
BfTypeDef* mFunctionTypeDef;
BfTypeDef* mGCTypeDef;
BfTypeDef* mGenericIEnumerableTypeDef;
BfTypeDef* mGenericIEnumeratorTypeDef;

View file

@ -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()))
bool requiresConst = false;
if ((mModule->mCurMethodInstance == NULL) || (mModule->mCurMethodInstance->mMethodDef->mMethodType != BfMethodType_Mixin))
requiresConst = true;
if ((requiresConst) && (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);
}
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++;

View file

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

View file

@ -830,7 +830,6 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild
{
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();

View file

@ -143,6 +143,7 @@ public:
BfPopulateType mPopulateType;
BfTypeReference* mCurBaseTypeRef;
BfTypeInstance* mCurBaseType;
BfTypeReference* mCurAttributeTypeRef;
BfFieldDef* mCurFieldDef;
BfTypeDef* mCurTypeDef;
@ -160,6 +161,7 @@ public:
mPopulateType = BfPopulateType_Identity;
mCurBaseTypeRef = NULL;
mCurBaseType = NULL;
mCurFieldDef = NULL;
mCurAttributeTypeRef = NULL;
mCurTypeDef = NULL;

View file

@ -445,16 +445,6 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio
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)
{
if ((!mCurTypeDef->mIsAbstract) && (mCurTypeDef->mTypeCode != BfTypeCode_Interface))
@ -1780,19 +1770,16 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
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,6 +1905,7 @@ 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;
@ -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);

View file

@ -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)
@ -10207,10 +10220,41 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie
{
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;
@ -10259,13 +10303,13 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie
}
}
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
@ -11932,6 +11976,7 @@ void BfExprEvaluator::VisitLambdaBodies(BfAstNode* body, BfFieldDtorDeclaration*
while (fieldDtor != NULL)
{
mModule->mCurMethodState->mLeftBlockUncond = false;
mModule->VisitChild(fieldDtor->mBody);
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;
}
@ -18712,9 +18768,9 @@ void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr)
for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
{
BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
++valueIdx;
if (fieldInstance->mResolvedType->IsValuelessType())
continue;
++valueIdx;
auto typedVal = typedValues[valueIdx];
if (!typedVal)
{
@ -20404,6 +20460,65 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp
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;

View file

@ -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,14 +4730,36 @@ 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->mConstType = BfConstType_GlobalVar;
constGV->mType = varType;
constGV->mIsConst = isConstant;
constGV->mLinkageType = linkageType;
@ -4758,23 +4767,15 @@ BfIRValue BfIRBuilder::CreateGlobalVariable(BfIRType varType, bool isConstant, B
constGV->mName = AllocStr(name);
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);
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;
}

View file

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

View file

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

View file

@ -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();
mUnreifiedStringPoolRefs.Clear();
}
mDllImportEntries.Clear();
mImportFileNames.Clear();
for (auto& pairVal : mDeferredMethodCallData)
@ -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,28 +1693,34 @@ 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);
if ((mBfIRBuilder->mIgnoreWrites) && (!force))
{
mUnreifiedStringPoolRefs.Add(strId);
return mBfIRBuilder->CreateConst(BfTypeCode_StringId, strId);
}
BfIRValue* irValuePtr = NULL;
if (!mStringObjectPool.TryAdd(strId, NULL, &irValuePtr))
return *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
{
@ -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++)
{
@ -6529,6 +6568,35 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
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;
@ -7448,7 +7525,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
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;
@ -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);
@ -11019,7 +11134,7 @@ 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,7 +11629,6 @@ 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:
@ -11520,6 +11636,10 @@ BfVariant BfModule::TypedValueToVariant(BfAstNode* refNode, const BfTypedValue&
variant.mTypeCode = constant->mTypeCode;
variant.mInt64 = constant->mInt64;
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
{
@ -13656,15 +13783,10 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance)
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);
}
}
@ -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;
@ -14060,7 +14155,9 @@ void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, bool doAli
{
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());
@ -18286,6 +18381,35 @@ 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 (importStrNum != -1)
{
if (customAttr.mType->mTypeDef->mFullName.ToString() == "System.ImportAttribute")
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];
@ -21558,7 +21672,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
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))

View file

@ -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,11 +1539,11 @@ 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 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);
@ -1553,8 +1554,9 @@ public:
void pm(BfMethodInstance* type);
void CurrentAddToConstHolder(BfIRValue& irVal);
void ClearConstData();
bool HasUnactializedConstant(BfConstant* constant, BfIRConstHolder* constHolder);
BfTypedValue GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType);
BfIRValue ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType, bool allowStringId = false);
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);
@ -1772,11 +1774,11 @@ public:
BfType* FixIntUnknown(BfType* type);
void FixIntUnknown(BfTypedValue& typedVal, BfType* matchType = NULL);
void FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs);
void FixValueActualization(BfTypedValue& typedVal);
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);

View file

@ -164,6 +164,7 @@ 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);
@ -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)
{
@ -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,7 +9822,8 @@ 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);
@ -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,16 +10018,17 @@ 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;
if (genericArgDiffCount != 0)
@ -9989,12 +10046,26 @@ 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++;
}
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);
@ -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

View file

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

View file

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

View file

@ -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();
@ -2874,7 +2876,7 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
{
BfTypeInstance* genericType = (BfTypeInstance*)type;
for (auto genericArg : genericType->mGenericTypeInfo->mTypeGenericArguments)
hashVal = ((hashVal ^ (Hash(genericArg, ctx))) << 5) - hashVal;
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))))
@ -3073,7 +3083,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
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;
}
}
}
@ -3156,11 +3170,11 @@ 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;
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;
}
@ -3171,7 +3185,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
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))
@ -3295,7 +3309,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
ctx->mRootTypeDef = ctx->mModule->mCompiler->mNullableTypeDef;
int hashVal = ctx->mModule->mCompiler->mNullableTypeDef->mHash;
hashVal = ((hashVal ^ (Hash(nullableType->mElementType, ctx))) << 5) - hashVal;
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)
{

View file

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

View file

@ -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,10 +447,12 @@ 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;
}
@ -449,14 +460,20 @@ void BfSourceClassifier::Visit(BfInvocationExpression* invocationExpr)
{
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);

View file

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

View file

@ -833,12 +833,26 @@ int BfTypeDef::GetSelfGenericParamCount()
BfMethodDef* BfTypeDef::GetMethodByName(const StringImpl& name, int paramCount)
{
for (auto method : mMethods)
PopulateMemberSets();
BfMemberSetEntry* entry = NULL;
if (!mMethodSet.TryGetWith(name, &entry))
return NULL;
BfMethodDef* bestMethodDef = NULL;
auto methodDef = (BfMethodDef*)entry->mMemberDef;
while (methodDef != NULL)
{
if ((name == method->mName) && ((paramCount == -1) || (paramCount == (int)method->mParams.size())))
return method;
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)
@ -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);
}

View file

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

View file

@ -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);
@ -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);
@ -6933,7 +6958,6 @@ CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance, BfIRValue f
ceFunction->mIsVarReturn = methodInstance->mReturnType->IsVar();
ceFunction->mCeFunctionInfo = ceFunctionInfo;
ceFunction->mMethodInstance = methodInstance;
ceFunctionInfo->mMethodInstance = methodInstance;
ceFunctionInfo->mCeFunction = ceFunction;
MapFunctionId(ceFunction);

View file

@ -120,6 +120,7 @@ enum DwEvalExpressionFlags : int16
DwEvalExpressionFlag_MemoryWatch = 0x80,
DwEvalExpressionFlag_Symbol = 0x100,
DwEvalExpressionFlag_StepIntoCalls = 0x200,
DwEvalExpressionFlag_RawStr = 0x400
};
struct DwDisplayInfo

View file

@ -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);
}
if (mCURL != NULL)
curl_easy_cleanup(mCURL);
if (mCURLMulti != NULL)
{
curl_multi_cleanup(mCURLMulti);
}
mCURL = NULL;
mCURLMulti = NULL;
}
void NetRequest::DoTransfer()
@ -105,66 +102,76 @@ 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)
long response_code = 0;
for (int pass = 0; pass < 3; pass++)
{
mNetManager->mDebugManager->OutputRawMessage(StrFormat("symsrv Getting '%s'", mURL.c_str()));
}
BfLogDbg("NetManager starting get on %s Pass:%d\n", mURL.c_str(), pass);
mNetManager->mDebugManager->OutputRawMessage(StrFormat("msgLo Getting '%s'\n", mURL.c_str()));
//OutputDebugStrF("Getting '%s'\n", mURL.c_str());
mOutTempPath = mOutPath + "__partial";
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);
mCURLMulti = curl_multi_init();
CURLMcode mcode = curl_multi_add_handle(mCURLMulti, mCURL);
if (mcode != CURLM_OK)
{
mFailed = true;
return;
}
mCURL = curl_easy_init();
while (true)
{
int activeCount = 0;
curl_multi_perform(mCURLMulti, &activeCount);
if (activeCount == 0)
break;
if (mShowTracking)
{
mNetManager->mDebugManager->OutputRawMessage(StrFormat("symsrv Getting '%s'", mURL.c_str()));
}
int waitRet = 0;
curl_multi_wait(mCURLMulti, NULL, 0, 20, &waitRet);
//OutputDebugStrF("Getting '%s'\n", mURL.c_str());
if (mCancelling)
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;
}
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;
// }
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 (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));
if (response_code == 200)
{
curl_off_t downloadSize = 0;

View file

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

View file

@ -161,6 +161,32 @@ namespace Tests
}
}
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
{
public T mTVal;
@ -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]

View file

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

View file

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

View file

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