1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 03:52:19 +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; mDragKind = .None;
} }
if (Math.Abs(dY) < mSelfHeight * 0.21f)
{
mDragKind = .None;
mDragTarget = null;
return;
}
delete mCurDragEvent; delete mCurDragEvent;
mCurDragEvent = new DragEvent(); mCurDragEvent = new DragEvent();
mCurDragEvent.mX = x; mCurDragEvent.mX = x;

View file

@ -106,6 +106,24 @@ namespace Beefy.widgets
extension KeyCode 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) public static Result<KeyCode> Parse(StringView str)
{ {
if (str.Length == 1) if (str.Length == 1)

View file

@ -200,7 +200,8 @@ namespace Beefy.widgets
{ {
return (mTabbedView.mParentDockingFrame.mParentDockingFrame == null) && return (mTabbedView.mParentDockingFrame.mParentDockingFrame == null) &&
(mTabbedView.mParentDockingFrame.GetDockedWindowCount() == 1) && (mTabbedView.mParentDockingFrame.GetDockedWindowCount() == 1) &&
(mTabbedView.GetTabCount() == 1); (mTabbedView.GetTabCount() == 1) &&
mTabbedView.mAutoClose;
} }
void WindowDragLostFocusHandler(BFWindow window, BFWindow newFocus) void WindowDragLostFocusHandler(BFWindow window, BFWindow newFocus)
@ -237,7 +238,7 @@ namespace Beefy.widgets
300, 500, 300, 500,
BFWindowBase.Flags.Border | BFWindowBase.Flags.ThickFrame | BFWindowBase.Flags.Resizable | BFWindowBase.Flags.SysMenu | 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.Caption | BFWindowBase.Flags.Minimize | BFWindowBase.Flags.ToolWindow | BFWindowBase.Flags.TopMost |
BFWindowBase.Flags.UseParentMenu, BFWindowBase.Flags.UseParentMenu | BFWindowBase.Flags.Maximize,
subFrame); subFrame);
Dock(subFrame, null, DockingFrame.WidgetAlign.Top); Dock(subFrame, null, DockingFrame.WidgetAlign.Top);
//subFrame.AddDockedWidget(fourthTabbedView, null, DockingFrame.WidgetAlign.Left, false); //subFrame.AddDockedWidget(fourthTabbedView, null, DockingFrame.WidgetAlign.Left, false);
@ -288,7 +289,7 @@ namespace Beefy.widgets
if ((refWidget != null) && (refWidget.mWidgetWindow != mWidgetWindow) && (mWidgetWindow != null)) if ((refWidget != null) && (refWidget.mWidgetWindow != mWidgetWindow) && (mWidgetWindow != null))
mWidgetWindow.SetForeground(); mWidgetWindow.SetForeground();
if (mTabbedView.GetTabCount() == 1) if ((mTabbedView.GetTabCount() == 1) && mTabbedView.mAutoClose)
{ {
mTabbedView.Dock(frame, refWidget, align); mTabbedView.Dock(frame, refWidget, align);
return; return;
@ -327,7 +328,7 @@ namespace Beefy.widgets
tabbedView.Dock(frame, refWidget, align); tabbedView.Dock(frame, refWidget, align);
} }
if (prevTabbedView.GetTabCount() == 0) if ((prevTabbedView.GetTabCount() == 0) && prevTabbedView.mAutoClose)
{ {
prevTabbedView.mParentDockingFrame.RemoveDockedWidget(prevTabbedView); 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); public static extern int32 GetDisplayMode(int32 displayIndex, int32 modeIndex, out SDL_DisplayMode mode);
/* Available in 2.0.5 or higher */ /* Available in 2.0.5 or higher */
[LinkName("SDL_GetDisplayMode")] [LinkName("SDL_GetDisplayUsableBounds")]
public static extern int SDL_GetDisplayUsableBounds(int displayIndex, out Rect rect); public static extern int SDL_GetDisplayUsableBounds(int displayIndex, out Rect rect);
[LinkName("SDL_GetNumDisplayModes")] [LinkName("SDL_GetNumDisplayModes")]

View file

@ -119,7 +119,8 @@ namespace System.IO
DeleteAndNullify!(mTitle); DeleteAndNullify!(mTitle);
DeleteAndNullify!(mInitialDir); DeleteAndNullify!(mInitialDir);
DeleteAndNullify!(mDefaultExt); DeleteAndNullify!(mDefaultExt);
DeleteAndNullify!(mFileNames); DeleteContainerAndItems!(mFileNames);
mFileNames = null;
DeleteAndNullify!(mFilter); DeleteAndNullify!(mFilter);
mFilterIndex = 1; mFilterIndex = 1;
mSupportMultiDottedExtensions = false; 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:4065)
#pragma warning(disable:4996) #pragma warning(disable:4996)

View file

@ -164,17 +164,30 @@ public:
{ {
auto newHashHeads = (Entry**)TFuncs::AllocateZero(sizeof(Entry*) * newHashSize, alignof(Entry*)); auto newHashHeads = (Entry**)TFuncs::AllocateZero(sizeof(Entry*) * newHashSize, alignof(Entry*));
SizedArray<Entry*, 32> entryList;
for (int hashIdx = 0; hashIdx < mHashSize; hashIdx++) for (int hashIdx = 0; hashIdx < mHashSize; hashIdx++)
{ {
Entry* checkEntry = mHashHeads[hashIdx]; Entry* checkEntry = mHashHeads[hashIdx];
if (checkEntry != NULL)
{
// We want to keep elements with equal hashes in their insert order so we need to
// iterate through the linked list in reverse
entryList.Clear();
while (checkEntry != NULL) while (checkEntry != NULL)
{ {
auto nextEntry = checkEntry->mNext; 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; int newHashIdx = (checkEntry->mHash & 0x7FFFFFFF) % newHashSize;
checkEntry->mNext = newHashHeads[newHashIdx]; checkEntry->mNext = newHashHeads[newHashIdx];
newHashHeads[newHashIdx] = checkEntry; newHashHeads[newHashIdx] = checkEntry;
}
checkEntry = nextEntry;
} }
} }

View file

@ -12,7 +12,8 @@ namespace gen
{ {
class Program 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) public static int Main(String[] args)
{ {

View file

@ -29,12 +29,8 @@ namespace IDE
public int32 mUpdateCnt; public int32 mUpdateCnt;
public Project mHotProject; public Project mHotProject;
public Workspace.Options mWorkspaceOptions; public Workspace.Options mWorkspaceOptions;
public Dictionary<Project, String> mImpLibMap = new .() ~ public Dictionary<Project, String> mImpLibMap = new .() ~ DeleteDictionaryAndValues!(_);
{ public Dictionary<Project, String> mTargetPathMap = new .() ~ DeleteDictionaryAndValues!(_);
for (let val in _.Values)
delete val;
delete _;
};
public ScriptManager.Context mScriptContext = new .() ~ _.ReleaseLastRef(); public ScriptManager.Context mScriptContext = new .() ~ _.ReleaseLastRef();
public ScriptManager mScriptManager ~ delete _; public ScriptManager mScriptManager ~ delete _;
@ -122,7 +118,7 @@ namespace IDE
bool didCommands = false; 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); //Console.WriteLine("Executing custom command {0} {1} {2}", highestDateTime, targetDateTime, forceRebuild);
for (let origCustomCmd in cmdList) for (let origCustomCmd in cmdList)
@ -163,19 +159,13 @@ namespace IDE
didCommands = true; 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; 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; return didCommands ? .HadCommands : .NoCommands;
} }
@ -874,9 +864,9 @@ namespace IDE
minRTModName.Insert(0, "_"); minRTModName.Insert(0, "_");
if (!is64Bit) 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 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 "); 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); 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(); String linkerPath = scope String();
linkerPath.Append(binPath);
linkerPath.Append("/link.exe");
if (workspaceOptions.mToolsetType == .LLVM) if (workspaceOptions.mToolsetType == .LLVM)
{ {
linkerPath.Clear(); linkerPath.Clear();
@ -1097,6 +1078,17 @@ namespace IDE
if ((mPlatformType == .Windows) && (!is64Bit)) if ((mPlatformType == .Windows) && (!is64Bit))
linkLine.Append(" /safeseh:no"); 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) if (options.mBuildOptions.mBeefLibType != .DynamicDebug)
{ {
@ -1216,6 +1208,8 @@ namespace IDE
} }
} }
mTargetPathMap[project] = new String(targetPath);
if (hotProject == null) if (hotProject == null)
{ {
switch (QueueProjectCustomBuildCommands(project, targetPath, compileKind.WantsRunAfter ? options.mBuildOptions.mBuildCommandsOnRun : options.mBuildOptions.mBuildCommandsOnCompile, options.mBuildOptions.mPreBuildCmds)) 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 (project.mGeneralOptions.mTargetType == .CustomBuild)
{ {
if (hotProject == null)
DoPostBuild();
return true; return true;
} }
@ -1402,7 +1383,31 @@ namespace IDE
return false; 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; return true;
} }
} }

View file

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

View file

@ -436,6 +436,12 @@ namespace IDE
} }
} }
public class ScriptCmd : ExecutionCmd
{
public String mCmd ~ delete _;
public String mPath ~ delete _;
}
public enum ArgsFileKind public enum ArgsFileKind
{ {
None, None,
@ -7448,19 +7454,38 @@ namespace IDE
} }
} }
if ((mKeyChordState != null) && (evt.mKeyCode.IsModifier))
{
// Ignore
}
else
{
var keyState = scope KeyState(); var keyState = scope KeyState();
keyState.mKeyCode = evt.mKeyCode; keyState.mKeyCode = evt.mKeyCode;
keyState.mKeyFlags = evt.mKeyFlags; keyState.mKeyFlags = evt.mKeyFlags;
var curKeyMap = mCommands.mKeyMap; var curKeyMap = mCommands.mKeyMap;
bool hadChordState = mKeyChordState != null; bool hadChordState = mKeyChordState != null;
if (mKeyChordState != null) if (mKeyChordState != null)
curKeyMap = mKeyChordState.mCommandMap; curKeyMap = mKeyChordState.mCommandMap;
DeleteAndNullify!(mKeyChordState); var prevKeyChordState = mKeyChordState;
defer delete prevKeyChordState;
mKeyChordState = null;
KeyState matchedKey; KeyState matchedKey;
IDECommandBase commandBase; IDECommandBase commandBase;
if (curKeyMap.mMap.TryGet(keyState, out matchedKey, out commandBase))
bool hadMatch = curKeyMap.mMap.TryGet(keyState, out matchedKey, out commandBase);
if ((!hadMatch) && (prevKeyChordState != null))
{
// 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) if (var commandMap = commandBase as CommandMap)
{ {
@ -7526,6 +7551,7 @@ namespace IDE
return; return;
} }
} }
}
SourceViewPanel sourceViewPanel = null; SourceViewPanel sourceViewPanel = null;
Widget focusWidget = window.mFocusWidget; Widget focusWidget = window.mFocusWidget;
@ -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; defer delete next;
mExecutionQueue.RemoveAt(0); mExecutionQueue.RemoveAt(0);
@ -8411,6 +8452,11 @@ namespace IDE
if (gApp.mDebugger.mIsRunning) if (gApp.mDebugger.mIsRunning)
mProfilePanel.StartProfiling(profileCmd.mThreadId, profileCmd.mDesc, profileCmd.mSampleRate); mProfilePanel.StartProfiling(profileCmd.mThreadId, profileCmd.mDesc, profileCmd.mSampleRate);
} }
else if (var scriptCmd = next as ScriptCmd)
{
// Already handled
(void)scriptCmd;
}
else else
{ {
Runtime.FatalError("Unknown command"); 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) 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); result.Append(configString);
bool hadError = false; bool hadError = false;
@ -9258,6 +9305,28 @@ namespace IDE
cmdErr = "Invalid number of arguments"; cmdErr = "Invalid number of arguments";
case "Var": case "Var":
break ReplaceBlock; 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) if (newString == null)
@ -10251,6 +10320,12 @@ namespace IDE
success = false; success = false;
} }
for (var project in orderedProjectList)
{
if (!mBuildContext.QueueProjectPostBuild(project, hotProject, completedCompileCmd, hotFileNames, compileKind))
success = false;
}
if (hotFileNames.Count > 0) if (hotFileNames.Count > 0)
{ {
// Why were we rehupping BEFORE hotLoad? // Why were we rehupping BEFORE hotLoad?
@ -10430,6 +10505,36 @@ namespace IDE
#endif #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) protected bool Compile(CompileKind compileKind = .Normal, Project hotProject = null)
{ {
Debug.Assert(mBuildContext == 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()) if (!mSettings.mVSSettings.IsConfigured())
mSettings.mVSSettings.SetDefaults(); mSettings.mVSSettings.SetDefaults();
@ -10788,8 +10893,8 @@ namespace IDE
//options.mDebugOptions.mCommand //options.mDebugOptions.mCommand
String launchPath = scope String(); String launchPathRel = scope String();
ResolveConfigString(mPlatformName, workspaceOptions, project, options, options.mDebugOptions.mCommand, "debug command", launchPath); ResolveConfigString(mPlatformName, workspaceOptions, project, options, options.mDebugOptions.mCommand, "debug command", launchPathRel);
String arguments = scope String(); String arguments = scope String();
ResolveConfigString(mPlatformName, workspaceOptions, project, options, "$(Arguments)", "debug command arguments", arguments); ResolveConfigString(mPlatformName, workspaceOptions, project, options, "$(Arguments)", "debug command arguments", arguments);
String workingDirRel = scope String(); String workingDirRel = scope String();
@ -10797,6 +10902,9 @@ namespace IDE
var workingDir = scope String(); var workingDir = scope String();
Path.GetAbsolutePath(workingDirRel, project.mProjectDir, workingDir); Path.GetAbsolutePath(workingDirRel, project.mProjectDir, workingDir);
String launchPath = scope String();
Path.GetAbsolutePath(launchPathRel, workingDir, launchPath);
String targetPath = scope .(); String targetPath = scope .();
ResolveConfigString(mPlatformName, workspaceOptions, project, options, "$(TargetPath)", "Target path", targetPath); ResolveConfigString(mPlatformName, workspaceOptions, project, options, "$(TargetPath)", "Target path", targetPath);

View file

@ -1007,7 +1007,7 @@ namespace IDE
if (!gApp.[Friend]mExecutionQueue.IsEmpty) if (!gApp.[Friend]mExecutionQueue.IsEmpty)
{ {
var nextCmd = gApp.mExecutionQueue[0]; var nextCmd = gApp.mExecutionQueue[0];
if (!(nextCmd is IDEApp.TargetCompletedCmd)) if (!(nextCmd is IDEApp.ScriptCmd))
return false; return false;
} }

View file

@ -876,17 +876,23 @@ namespace IDE.ui
{ {
base.Update(); base.Update();
if (gApp.mBfResolveCompiler == null)
return;
var focusedItem = (ClassViewListViewItem)mTypeLV.GetRoot().FindFocusedItem(); var focusedItem = (ClassViewListViewItem)mTypeLV.GetRoot().FindFocusedItem();
var focusedStr = scope String(); var focusedStr = scope String();
if (focusedItem != null) if (focusedItem != null)
GetName(focusedItem, focusedStr); GetName(focusedItem, focusedStr);
if (gApp.mBfResolveCompiler != null)
{
int32 compileRevision = gApp.mBfResolveCompiler.GetCompileRevision(); int32 compileRevision = gApp.mBfResolveCompiler.GetCompileRevision();
if (mLastCompileRevision != compileRevision) if (mLastCompileRevision != compileRevision)
{ {
mCompileRevisionDirtyDelay = 30; mCompileRevisionDirtyDelay = 30;
mLastCompileRevision = compileRevision; mLastCompileRevision = compileRevision;
} }
}
if ((mCompileRevisionDirtyDelay > 0) && (--mCompileRevisionDirtyDelay == 0)) if ((mCompileRevisionDirtyDelay > 0) && (--mCompileRevisionDirtyDelay == 0))
{ {

View file

@ -266,7 +266,7 @@ namespace IDE.ui
IdSpan liveCharIdData; IdSpan liveCharIdData;
String liveText = scope:: String(); String liveText = scope:: String();
app.FindProjectSourceContent(projectSource, out liveCharIdData, true, liveText, null); app.FindProjectSourceContent(projectSource, out liveCharIdData, true, liveText, null);
defer(stack) liveCharIdData.Dispose(); defer:: liveCharIdData.Dispose();
var compileInstance = IDEApp.sApp.mWorkspace.GetProjectSourceCompileInstance(projectSource, mHotIdx); var compileInstance = IDEApp.sApp.mWorkspace.GetProjectSourceCompileInstance(projectSource, mHotIdx);
if (compileInstance == null) if (compileInstance == null)

View file

@ -276,7 +276,15 @@ namespace IDE.ui
SetLabel(item, codeStr); SetLabel(item, codeStr);
let descItem = item.GetSubItem(1); 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', ' '); errStr.Replace('\n', ' ');
SetLabel(descItem, errStr); SetLabel(descItem, errStr);

View file

@ -718,6 +718,14 @@ namespace IDE.ui
var watch = useListViewItem.mWatchEntry; var watch = useListViewItem.mWatchEntry;
String.NewOrSet!(watch.mName, displayString); String.NewOrSet!(watch.mName, displayString);
String.NewOrSet!(watch.mEvalStr, evalString); String.NewOrSet!(watch.mEvalStr, evalString);
if (watch.mEvalStr.StartsWith("!raw"))
{
for (int i < 4)
watch.mEvalStr[i] = ' ';
watch.mResultType = .RawText;
}
useListViewItem.mWatchEntry = watch; useListViewItem.mWatchEntry = watch;
if (!isLiteral) if (!isLiteral)
useListViewItem.Label = displayString; useListViewItem.Label = displayString;
@ -730,7 +738,7 @@ namespace IDE.ui
String val = scope String(); String val = scope String();
if (evalString.StartsWith(":", StringComparison.Ordinal)) if (evalString.StartsWith(":", StringComparison.Ordinal))
{ {
var showString = scope String(evalString, 1); var showString = scope String(4096)..Append(evalString, 1);
bool isShowingDoc = showString.Contains('\x01'); bool isShowingDoc = showString.Contains('\x01');
if (!isShowingDoc) if (!isShowingDoc)
{ {
@ -759,11 +767,13 @@ namespace IDE.ui
flags |= .AllowSideEffects | .AllowCalls; flags |= .AllowSideEffects | .AllowCalls;
if (gApp.mSettings.mDebuggerSettings.mAutoEvaluateProperties) if (gApp.mSettings.mDebuggerSettings.mAutoEvaluateProperties)
flags |= .AllowProperties; flags |= .AllowProperties;
if (watch.mResultType == .RawText)
flags |= .RawStr;
DebugManager.Language language = mLanguage; DebugManager.Language language = mLanguage;
if (parentWatchEntry != null) if (parentWatchEntry != null)
language = parentWatchEntry.mLanguage; language = parentWatchEntry.mLanguage;
gApp.DebugEvaluate(null, evalString, val, -1, language, flags); gApp.DebugEvaluate(null, watch.mEvalStr, val, -1, language, flags);
} }
if (val == "!pending") if (val == "!pending")
{ {
@ -773,6 +783,13 @@ namespace IDE.ui
} }
watch.mIsPending = false; watch.mIsPending = false;
} }
if (watch.mResultType == .RawText)
{
String.NewOrSet!(valueSubItem.mLabel, val);
return useListViewItem;
}
var vals = scope List<StringView>(val.Split('\n')); var vals = scope List<StringView>(val.Split('\n'));
//if (!vals[0].IsEmpty) //if (!vals[0].IsEmpty)

View file

@ -7,6 +7,7 @@ using Beefy.theme.dark;
using Beefy.gfx; using Beefy.gfx;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using IDE.Debugger;
namespace IDE.ui namespace IDE.ui
{ {
@ -379,6 +380,10 @@ namespace IDE.ui
var subItemLabel = result.GetSubItem(1).mLabel; var subItemLabel = result.GetSubItem(1).mLabel;
if (subItemLabel == null) if (subItemLabel == null)
subItemLabel = ""; subItemLabel = "";
if (result.mWatchEntry.mResultType == .RawText)
mEditWidgetContent.AppendText(scope String(subItemLabel, "\n"));
else
mEditWidgetContent.AppendText(scope String(" ", subItemLabel, "\n")); mEditWidgetContent.AppendText(scope String(" ", subItemLabel, "\n"));
if (result.mWatchEntry.mWarnings != null) if (result.mWatchEntry.mWarnings != null)
@ -415,6 +420,10 @@ namespace IDE.ui
for (int32 i = startPos; i < mEditWidgetContent.mData.mTextLength; i++) for (int32 i = startPos; i < mEditWidgetContent.mData.mTextLength; i++)
mEditWidgetContent.mData.mText[i].mDisplayTypeId = (uint8)SourceElementType.Error; mEditWidgetContent.mData.mText[i].mDisplayTypeId = (uint8)SourceElementType.Error;
} }
else if (result.mWatchEntry.mResultType == .RawText)
{
// No info button
}
else else
{ {
mInfoButton.Resize(resultX - GS!(3), resultY - GS!(2), GS!(20), GS!(20)); mInfoButton.Resize(resultX - GS!(3), resultY - GS!(2), GS!(20), GS!(20));
@ -547,7 +556,16 @@ namespace IDE.ui
} }
else 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; gApp.mIsImmediateDebugExprEval = true;
} }
} }
@ -570,8 +588,20 @@ namespace IDE.ui
} }
var info = scope String()..Append(val, idx + ":autocomplete\n".Length); var info = scope String()..Append(val, idx + ":autocomplete\n".Length);
if (!editWidgetContent.mAutoComplete.mIsDocumentationPass) 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); editWidgetContent.mAutoComplete.SetInfo(info, true, mEntryStartPos.mIndex + 1);
} }
}
else if (editWidgetContent.mAutoComplete != null) else if (editWidgetContent.mAutoComplete != null)
editWidgetContent.mAutoComplete.Close(); editWidgetContent.mAutoComplete.Close();
} }

View file

@ -284,26 +284,20 @@ namespace IDE.ui
s.AppendF("0x{:A}", (uint64)lockRange.mBaseOffset); s.AppendF("0x{:A}", (uint64)lockRange.mBaseOffset);
case RepType.Int8: case RepType.Int8:
hasAltS = true; hasAltS = true;
(*(int8*)lockRange.mData.CArray()).ToString(s, (altIntBase == 10) ? "" : "X2", null); (*(int8*)lockRange.mData.CArray()).ToString(s, (intBase == 10) ? "" : "X2", null);
if (altIntBase == 10) ((UInt64)*(uint8*)lockRange.mData.CArray()).ToString(altS, (altIntBase == 10) ? "" : "X2", null);
((UInt64)*(uint8*)lockRange.mData.CArray()).ToString(altS, "", null);
case RepType.Int16: case RepType.Int16:
hasAltS = true; hasAltS = true;
(*(int16*)lockRange.mData.CArray()).ToString(s, (altIntBase == 10) ? "" : "X4", null); (*(int16*)lockRange.mData.CArray()).ToString(s, (intBase == 10) ? "" : "X4", null);
if (altIntBase == 10) ((UInt64)*(uint16*)lockRange.mData.CArray()).ToString(altS, (altIntBase == 10) ? "" : "X4", null);
((UInt64)*(uint16*)lockRange.mData.CArray()).ToString(altS, "", null);
case RepType.Int32: case RepType.Int32:
hasAltS = true; hasAltS = true;
(*(int32*)lockRange.mData.CArray()).ToString(s, (altIntBase == 10) ? "" : "X8", null); (*(int32*)lockRange.mData.CArray()).ToString(s, (intBase == 10) ? "" : "X8", null);
if (altIntBase == 10) ((UInt64)*(uint32*)lockRange.mData.CArray()).ToString(altS, (altIntBase == 10) ? "" : "X8", null);
((UInt64)*(uint32*)lockRange.mData.CArray()).ToString(altS, "", null);
case RepType.Int64: case RepType.Int64:
hasAltS = true; hasAltS = true;
(*(int64*)lockRange.mData.CArray()).ToString(s, (altIntBase == 10) ? "" : "X16", null); (*(int64*)lockRange.mData.CArray()).ToString(s, (intBase == 10) ? "" : "X16", null);
if (altIntBase == 0x10) ((UInt64)*(uint64*)lockRange.mData.CArray()).ToString(altS, (altIntBase == 10) ? "" : "X16", null);
s.Insert(8, '\'');
if (altIntBase == 10)
((UInt64)*(uint64*)lockRange.mData.CArray()).ToString(altS, "", null);
case RepType.Float: case RepType.Float:
(*(float*)lockRange.mData.CArray()).ToString(s); (*(float*)lockRange.mData.CArray()).ToString(s);
case RepType.Double: case RepType.Double:

View file

@ -187,9 +187,10 @@ namespace IDE.ui
{ {
base.FocusForKeyboard(); base.FocusForKeyboard();
SetFocus(); 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"); var undoBatchStart = new UndoBatchStart("pasteText");
mData.mUndoManager.Add(undoBatchStart); mData.mUndoManager.Add(undoBatchStart);
defer(stack) mData.mUndoManager.Add(undoBatchStart.mBatchEnd); defer:: mData.mUndoManager.Add(undoBatchStart.mBatchEnd);
} }
if (HasSelection()) if (HasSelection())
@ -3644,7 +3644,7 @@ namespace IDE.ui
bool hadSuggestion = false; bool hadSuggestion = false;
List<String> suggestions = scope List<String>(); List<String> suggestions = scope List<String>();
defer (scope) ClearAndDeleteItems(suggestions); defer ClearAndDeleteItems(suggestions);
spellChecker.GetSuggestions(word, suggestions); spellChecker.GetSuggestions(word, suggestions);
for (var suggestion in suggestions) for (var suggestion in suggestions)
{ {
@ -3789,7 +3789,7 @@ namespace IDE.ui
else if (bfSystem != null) else if (bfSystem != null)
{ {
parser = bfSystem.CreateEmptyParser(null); parser = bfSystem.CreateEmptyParser(null);
defer(stack) delete parser; defer:: delete parser;
var text = scope String(); var text = scope String();
mEditWidget.GetText(text); mEditWidget.GetText(text);
parser.SetSource(text, mSourceViewPanel.mFilePath); parser.SetSource(text, mSourceViewPanel.mFilePath);

View file

@ -5073,7 +5073,11 @@ namespace IDE.ui
String showMouseoverString = null; String showMouseoverString = null;
if (bestError.mError != 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) if (bestError.mMoreInfo != null)
{ {
@ -5676,6 +5680,7 @@ namespace IDE.ui
} }
} }
if (gApp.mIsUpdateBatchStart)
UpdateMouseover(); UpdateMouseover();
var compiler = ResolveCompiler; var compiler = ResolveCompiler;

View file

@ -27,7 +27,8 @@ namespace IDE.ui
TypeClass = 0x80, TypeClass = 0x80,
TypeValueType = 0x100, TypeValueType = 0x100,
Namespace = 0x200, Namespace = 0x200,
Text = 0x400 Text = 0x400,
RawText = 0x800
} }
public class WatchEntry public class WatchEntry
@ -1740,6 +1741,7 @@ namespace IDE.ui
evt.mDragKind = .After; evt.mDragKind = .After;
dragTarget = (WatchListViewItem)dragTarget.mParentItem; dragTarget = (WatchListViewItem)dragTarget.mParentItem;
evt.mDragTarget = dragTarget; evt.mDragTarget = dragTarget;
return;
} }
if ((dragTarget.mLabel == "") && (dragKind == .After)) if ((dragTarget.mLabel == "") && (dragKind == .After))
dragKind = .Before; dragKind = .Before;

View file

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

View file

@ -3787,7 +3787,7 @@ BeMCOperand BeMCContext::AllocVirtualReg(BeType* type, int refCount, bool mustBe
if (mDebugging) if (mDebugging)
{ {
if (mcOperand.mVRegIdx == 6) if (mcOperand.mVRegIdx == 227)
{ {
NOP; NOP;
} }
@ -10364,7 +10364,7 @@ bool BeMCContext::DoLegalization()
inst->mArg0.mKind = BeMCOperandKind_SymbolAddr; inst->mArg0.mKind = BeMCOperandKind_SymbolAddr;
} }
ReplaceWithNewVReg(inst->mArg0, movInstIdx, true, false); ReplaceWithNewVReg(inst->mArg0, movInstIdx, true, false, true);
auto vregInfo = GetVRegInfo(inst->mArg0); auto vregInfo = GetVRegInfo(inst->mArg0);
vregInfo->mDisableR11 = true; vregInfo->mDisableR11 = true;
instIdx += 2; instIdx += 2;
@ -15842,7 +15842,7 @@ void BeMCContext::Generate(BeFunction* function)
mDbgPreferredRegs[32] = X64Reg_R8;*/ mDbgPreferredRegs[32] = X64Reg_R8;*/
//mDbgPreferredRegs[8] = X64Reg_RAX; //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 == "?MethodA@TestProgram@BeefTest@bf@@CAXXZ");
// || (function->mName == "?Hey@Blurg@bf@@SAXXZ") // || (function->mName == "?Hey@Blurg@bf@@SAXXZ")
// ; // ;

View file

@ -439,6 +439,7 @@ void BfCodeGenThread::RunLoop()
errorMsg += "\n"; errorMsg += "\n";
errorMsg += "Failed writing IR '" + fileName + "': " + ec.message(); errorMsg += "Failed writing IR '" + fileName + "': " + ec.message();
} }
else
fs.WriteSNZ(str); fs.WriteSNZ(str);
} }

View file

@ -341,11 +341,10 @@ BfCompiler::HotResolveData::~HotResolveData()
BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly) BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
{ {
//llvm::DebugFlag = true;
memset(&mStats, 0, sizeof(mStats)); memset(&mStats, 0, sizeof(mStats));
mCompletionPct = 0; mCompletionPct = 0;
mCanceling = false; mCanceling = false;
mHasRequiredTypes = false;
mNeedsFullRefresh = false; mNeedsFullRefresh = false;
mFastFinish = false; mFastFinish = false;
mHasQueuedTypeRebuilds = false; mHasQueuedTypeRebuilds = false;
@ -399,6 +398,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
mDbgRawAllocDataTypeDef = NULL; mDbgRawAllocDataTypeDef = NULL;
mDeferredCallTypeDef = NULL; mDeferredCallTypeDef = NULL;
mDelegateTypeDef = NULL; mDelegateTypeDef = NULL;
mFunctionTypeDef = NULL;
mActionTypeDef = NULL; mActionTypeDef = NULL;
mEnumTypeDef = NULL; mEnumTypeDef = NULL;
mFriendAttributeTypeDef = NULL; mFriendAttributeTypeDef = NULL;
@ -407,7 +407,6 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
mNoExtensionAttributeTypeDef = NULL; mNoExtensionAttributeTypeDef = NULL;
mCheckedAttributeTypeDef = NULL; mCheckedAttributeTypeDef = NULL;
mUncheckedAttributeTypeDef = NULL; mUncheckedAttributeTypeDef = NULL;
mFunctionTypeDef = NULL;
mGCTypeDef = NULL; mGCTypeDef = NULL;
mGenericIEnumerableTypeDef = NULL; mGenericIEnumerableTypeDef = NULL;
mGenericIEnumeratorTypeDef = NULL; mGenericIEnumeratorTypeDef = NULL;
@ -5107,6 +5106,18 @@ void BfCompiler::MarkStringPool(BfModule* module)
stringPoolEntry.mLastUsedRevision = mRevision; 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) /*if (module->mOptModule != NULL)
MarkStringPool(module->mOptModule);*/ MarkStringPool(module->mOptModule);*/
auto altModule = module->mNextAltModule; auto altModule = module->mNextAltModule;
@ -6596,7 +6607,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
BpEnter("Compile_Start"); BpEnter("Compile_Start");
bool hasRequiredTypes = true; mHasRequiredTypes = true;
//HashSet<BfTypeDef*> internalTypeDefs; //HashSet<BfTypeDef*> internalTypeDefs;
@ -6606,7 +6617,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
if (typeDef == NULL) if (typeDef == NULL)
{ {
mPassInstance->Fail(StrFormat("Unable to find system type: %s", typeName.c_str())); mPassInstance->Fail(StrFormat("Unable to find system type: %s", typeName.c_str()));
hasRequiredTypes = false; mHasRequiredTypes = false;
} }
return typeDef; return typeDef;
}; };
@ -6654,6 +6665,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
mDbgRawAllocDataTypeDef = _GetRequiredType("System.DbgRawAllocData"); mDbgRawAllocDataTypeDef = _GetRequiredType("System.DbgRawAllocData");
mDeferredCallTypeDef = _GetRequiredType("System.DeferredCall"); mDeferredCallTypeDef = _GetRequiredType("System.DeferredCall");
mDelegateTypeDef = _GetRequiredType("System.Delegate"); mDelegateTypeDef = _GetRequiredType("System.Delegate");
mFunctionTypeDef = _GetRequiredType("System.Function");
mActionTypeDef = _GetRequiredType("System.Action"); mActionTypeDef = _GetRequiredType("System.Action");
mEnumTypeDef = _GetRequiredType("System.Enum"); mEnumTypeDef = _GetRequiredType("System.Enum");
mFriendAttributeTypeDef = _GetRequiredType("System.FriendAttribute"); mFriendAttributeTypeDef = _GetRequiredType("System.FriendAttribute");
@ -6663,7 +6675,6 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
mCheckedAttributeTypeDef = _GetRequiredType("System.CheckedAttribute"); mCheckedAttributeTypeDef = _GetRequiredType("System.CheckedAttribute");
mUncheckedAttributeTypeDef = _GetRequiredType("System.UncheckedAttribute"); mUncheckedAttributeTypeDef = _GetRequiredType("System.UncheckedAttribute");
mResultTypeDef = _GetRequiredType("System.Result", 1); mResultTypeDef = _GetRequiredType("System.Result", 1);
mFunctionTypeDef = _GetRequiredType("System.Function");
mGCTypeDef = _GetRequiredType("System.GC"); mGCTypeDef = _GetRequiredType("System.GC");
mGenericIEnumerableTypeDef = _GetRequiredType("System.Collections.IEnumerable", 1); mGenericIEnumerableTypeDef = _GetRequiredType("System.Collections.IEnumerable", 1);
mGenericIEnumeratorTypeDef = _GetRequiredType("System.Collections.IEnumerator", 1); mGenericIEnumeratorTypeDef = _GetRequiredType("System.Collections.IEnumerator", 1);
@ -6722,13 +6733,11 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
mContext->mBfTypeType = NULL; mContext->mBfTypeType = NULL;
mContext->mBfClassVDataPtrType = NULL; mContext->mBfClassVDataPtrType = NULL;
if (!hasRequiredTypes) if (!mHasRequiredTypes)
{ {
// Force rebuilding // Force rebuilding
BfLogSysM("Compile missing required types\n"); BfLogSysM("Compile missing required types\n");
mInInvalidState = true;
mOptions.mForceRebuildIdx++; mOptions.mForceRebuildIdx++;
return true;
} }
mSystem->CheckLockYield(); mSystem->CheckLockYield();
@ -6736,8 +6745,6 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
mContext->mScratchModule->ResolveTypeDef(mBfObjectTypeDef); mContext->mScratchModule->ResolveTypeDef(mBfObjectTypeDef);
VisitSourceExteriorNodes(); VisitSourceExteriorNodes();
//BF_ASSERT(hasRequiredTypes);
if (!mIsResolveOnly) if (!mIsResolveOnly)
{ {
HashSet<BfModule*> foundVDataModuleSet; HashSet<BfModule*> foundVDataModuleSet;
@ -6812,18 +6819,13 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
if (mIsResolveOnly) if (mIsResolveOnly)
VisitAutocompleteExteriorIdentifiers(); VisitAutocompleteExteriorIdentifiers();
if (!hasRequiredTypes)
{
BfLogSysM("Missing required types\n");
}
mStats.mTypesQueued = 0; mStats.mTypesQueued = 0;
mStats.mMethodsQueued = 0; mStats.mMethodsQueued = 0;
mStats.mTypesQueued += (int)mContext->mPopulateTypeWorkList.size(); mStats.mTypesQueued += (int)mContext->mPopulateTypeWorkList.size();
mStats.mMethodsQueued += (int)mContext->mMethodWorkList.size(); mStats.mMethodsQueued += (int)mContext->mMethodWorkList.size();
if (hasRequiredTypes) //
{ {
mContext->mScratchModule->ResolveTypeDef(mBfObjectTypeDef, BfPopulateType_Full); mContext->mScratchModule->ResolveTypeDef(mBfObjectTypeDef, BfPopulateType_Full);
@ -6865,7 +6867,6 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
} }
} }
if (hasRequiredTypes)
ProcessPurgatory(true); ProcessPurgatory(true);
// Mark used modules // Mark used modules
@ -6967,7 +6968,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
} }
// Generate slot nums // Generate slot nums
if ((!mIsResolveOnly) && (hasRequiredTypes) && (!mCanceling)) if ((!mIsResolveOnly) && (!mCanceling))
{ {
if ((!IsHotCompile()) || (mHotState->mHasNewInterfaceTypes)) if ((!IsHotCompile()) || (mHotState->mHasNewInterfaceTypes))
{ {
@ -7099,12 +7100,11 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
DoWorkLoop(); DoWorkLoop();
} }
if (hasRequiredTypes)
ProcessPurgatory(false); ProcessPurgatory(false);
// Old Mark used modules // Old Mark used modules
if ((!mIsResolveOnly) && (hasRequiredTypes)) if (!mIsResolveOnly)
{ {
// if ((!mPassInstance->HasFailed()) && (!mCanceling)) // if ((!mPassInstance->HasFailed()) && (!mCanceling))
// { // {
@ -7161,7 +7161,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
String moduleListStr; String moduleListStr;
int numModulesWritten = 0; int numModulesWritten = 0;
if ((hasRequiredTypes) && (!mCanceling)) if (!mCanceling)
{ {
if (!mIsResolveOnly) if (!mIsResolveOnly)
{ {
@ -7251,8 +7251,6 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
while (true) while (true)
{ {
if (!hasRequiredTypes)
break;
if (mCanceling) if (mCanceling)
mCodeGen.Cancel(); mCodeGen.Cancel();
bool isDone = mCodeGen.Finish(); bool isDone = mCodeGen.Finish();
@ -7391,8 +7389,8 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
// gBEMemReporter.Report(); // gBEMemReporter.Report();
// int memReporterSize = gBEMemReporterSize; // int memReporterSize = gBEMemReporterSize;
mLastRevisionAborted = mCanceling || !hasRequiredTypes; mLastRevisionAborted = mCanceling;
bool didCancel = mCanceling && hasRequiredTypes; bool didCancel = mCanceling;
mCanceling = false; mCanceling = false;
mContext->ValidateDependencies(); 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<bool> prevIgnoreWarnings(bfCompiler->mContext->mScratchModule->mIgnoreWarnings, true);
SetAndRestoreValue<BfResolvePassData*> prevResolvePass(bfCompiler->mResolvePassData, &resolvePass); 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) if (type != NULL)
{ {
bfCompiler->mContext->mScratchModule->PopulateType(type);
outString += "Found"; outString += "Found";
if (auto typeInst = type->ToTypeInstance()) if (auto typeInst = type->ToTypeInstance())
{ {

View file

@ -323,6 +323,7 @@ public:
BfCodeGen mCodeGen; BfCodeGen mCodeGen;
String mOutputDirectory; String mOutputDirectory;
bool mCanceling; bool mCanceling;
bool mHasRequiredTypes;
bool mNeedsFullRefresh; bool mNeedsFullRefresh;
bool mFastFinish; bool mFastFinish;
bool mHasQueuedTypeRebuilds; // Infers we had a fast finish that requires a type rebuild bool mHasQueuedTypeRebuilds; // Infers we had a fast finish that requires a type rebuild
@ -352,6 +353,7 @@ public:
BfTypeDef* mDbgRawAllocDataTypeDef; BfTypeDef* mDbgRawAllocDataTypeDef;
BfTypeDef* mDeferredCallTypeDef; BfTypeDef* mDeferredCallTypeDef;
BfTypeDef* mDelegateTypeDef; BfTypeDef* mDelegateTypeDef;
BfTypeDef* mFunctionTypeDef;
BfTypeDef* mActionTypeDef; BfTypeDef* mActionTypeDef;
BfTypeDef* mEnumTypeDef; BfTypeDef* mEnumTypeDef;
BfTypeDef* mStringTypeDef; BfTypeDef* mStringTypeDef;
@ -359,7 +361,6 @@ public:
BfTypeDef* mTypeTypeDef; BfTypeDef* mTypeTypeDef;
BfTypeDef* mValueTypeTypeDef; BfTypeDef* mValueTypeTypeDef;
BfTypeDef* mResultTypeDef; BfTypeDef* mResultTypeDef;
BfTypeDef* mFunctionTypeDef;
BfTypeDef* mGCTypeDef; BfTypeDef* mGCTypeDef;
BfTypeDef* mGenericIEnumerableTypeDef; BfTypeDef* mGenericIEnumerableTypeDef;
BfTypeDef* mGenericIEnumeratorTypeDef; BfTypeDef* mGenericIEnumeratorTypeDef;

View file

@ -137,11 +137,11 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
int stringId = mModule->GetStringPoolIdx(mResult.mValue); int stringId = mModule->GetStringPoolIdx(mResult.mValue);
if (stringId != -1) if (stringId != -1)
{ {
if ((flags & BfConstResolveFlag_RemapFromStringId) != 0) if ((flags & BfConstResolveFlag_ActualizeValues) != 0)
{ {
prevIgnoreWrites.Restore(); prevIgnoreWrites.Restore();
mModule->mBfIRBuilder->PopulateType(mResult.mType); 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); 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->FixIntUnknown(mResult);
mModule->FixValueActualization(mResult);
if ((flags & BfConstResolveFlag_NoActualizeValues) == 0)
mModule->FixValueActualization(mResult, !prevIgnoreWrites.mPrevVal || ((flags & BfConstResolveFlag_ActualizeValues) != 0));
return mResult; return mResult;
} }
@ -416,15 +418,22 @@ bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatch
} }
else else
{ {
if ((argValue.mValue.IsFake()) && (!argValue.mType->IsValuelessType())) bool requiresConst = false;
{
if ((mModule->mCurMethodInstance == NULL) || (mModule->mCurMethodInstance->mMethodDef->mMethodType != BfMethodType_Mixin)) if ((mModule->mCurMethodInstance == NULL) || (mModule->mCurMethodInstance->mMethodDef->mMethodType != BfMethodType_Mixin))
requiresConst = true;
if ((requiresConst) && (argValue.mValue.IsFake()) && (!argValue.mType->IsValuelessType()))
{ {
mModule->Fail("Expression does not evaluate to a constant value", argExpr); mModule->Fail("Expression does not evaluate to a constant value", argExpr);
} }
}
if (!argValue.mType->IsVar())
{
if ((!requiresConst) || (argValue.mValue.IsConst()) || (argValue.mType->IsValuelessType()))
llvmArgs.push_back(argValue.mValue); llvmArgs.push_back(argValue.mValue);
else
llvmArgs.push_back(mModule->GetDefaultValue(argValue.mType));
}
paramIdx++; paramIdx++;
} }
argIdx++; argIdx++;

View file

@ -15,9 +15,10 @@ enum BfConstResolveFlags
BfConstResolveFlag_ExplicitCast = 1, BfConstResolveFlag_ExplicitCast = 1,
BfConstResolveFlag_NoCast = 2, BfConstResolveFlag_NoCast = 2,
BfConstResolveFlag_AllowSoftFail = 4, BfConstResolveFlag_AllowSoftFail = 4,
BfConstResolveFlag_RemapFromStringId = 8, BfConstResolveFlag_ActualizeValues = 8,
BfConstResolveFlag_ArrayInitSize = 0x10, BfConstResolveFlag_NoActualizeValues = 0x10,
BfConstResolveFlag_AllowGlobalVariable = 0x20, BfConstResolveFlag_ArrayInitSize = 0x20,
BfConstResolveFlag_AllowGlobalVariable = 0x40,
}; };
class BfConstResolver : public BfExprEvaluator class BfConstResolver : public BfExprEvaluator

View file

@ -830,7 +830,6 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild
{ {
BfTypeInstance* typeInst = type->ToTypeInstance(); BfTypeInstance* typeInst = type->ToTypeInstance();
if (type->IsDeleting()) if (type->IsDeleting())
{ {
return; return;
@ -2517,11 +2516,6 @@ void BfContext::QueueMethodSpecializations(BfTypeInstance* typeInst, bool checkS
BP_ZONE("BfContext::QueueMethodSpecializations"); BP_ZONE("BfContext::QueueMethodSpecializations");
if (typeInst->mTypeId == 578)
{
NOP;
}
auto module = typeInst->mModule; auto module = typeInst->mModule;
if (module == NULL) if (module == NULL)
return; return;
@ -2917,10 +2911,21 @@ void BfContext::Cleanup()
// Clean up deleted BfTypes // Clean up deleted BfTypes
// These need to get deleted before the modules because we access mModule in the MethodInstance dtors // 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++)
{ {
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); BF_ASSERT(type->mRebuildFlags & BfTypeRebuildFlag_Deleted);
delete type; delete type;
mTypeGraveyard[i] = NULL;
}
} }
mTypeGraveyard.Clear(); mTypeGraveyard.Clear();

View file

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

View file

@ -445,16 +445,6 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio
methodDef->mIsVirtual = false; 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 (methodDef->mIsAbstract)
{ {
if ((!mCurTypeDef->mIsAbstract) && (mCurTypeDef->mTypeCode != BfTypeCode_Interface)) if ((!mCurTypeDef->mIsAbstract) && (mCurTypeDef->mTypeCode != BfTypeCode_Interface))
@ -1780,19 +1770,16 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
if (prevRevisionTypeDef->mDefState == BfTypeDef::DefState_AwaitingNewVersion) if (prevRevisionTypeDef->mDefState == BfTypeDef::DefState_AwaitingNewVersion)
{ {
if (prevRevisionTypeDef->mNextRevision != NULL)
{
BfLogSysM("Deleting unused nextRevision %p from prevRevision %p\n", prevRevisionTypeDef->mNextRevision, prevRevisionTypeDef);
delete prevRevisionTypeDef->mNextRevision; delete prevRevisionTypeDef->mNextRevision;
}
prevRevisionTypeDef->mNextRevision = mCurTypeDef; prevRevisionTypeDef->mNextRevision = mCurTypeDef;
BF_ASSERT(mCurTypeDef->mSystem != NULL); BF_ASSERT(mCurTypeDef->mSystem != NULL);
mCurActualTypeDef = prevRevisionTypeDef; mCurActualTypeDef = prevRevisionTypeDef;
doInsertNew = false; doInsertNew = false;
} }
else
{
if (prevRevisionTypeDef->mNextRevision != NULL)
prevRevisionTypeDef = prevRevisionTypeDef->mNextRevision;
prevRevisionTypeDef = NULL;
}
} }
else else
{ {
@ -1820,8 +1807,8 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
outerTypeDef->mNestedTypes.push_back(mCurActualTypeDef); 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, 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); typeDeclaration->GetSourceData(), mResolvePassData != NULL, isAutoCompleteTempType, prevRevisionTypeDef);
BF_ASSERT(mCurTypeDef->mNameEx == NULL); BF_ASSERT(mCurTypeDef->mNameEx == NULL);
@ -1875,9 +1862,9 @@ void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
if (mCurTypeDef->mFullHash == prevRevisionTypeDef->mFullHash) 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; prevRevisionTypeDef->mDefState = BfTypeDef::DefState_Defined;
BF_ASSERT(prevRevisionTypeDef->mNextRevision == mCurTypeDef); BF_ASSERT(prevRevisionTypeDef->mNextRevision == mCurTypeDef);
prevRevisionTypeDef->mNextRevision = NULL; prevRevisionTypeDef->mNextRevision = NULL;
@ -1918,6 +1905,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
BfMethodDef* dynamicCastMethod = NULL; BfMethodDef* dynamicCastMethod = NULL;
BfMethodDef* toStringMethod = NULL; BfMethodDef* toStringMethod = NULL;
bool needsEqualsMethod = ((mCurTypeDef->mTypeCode == BfTypeCode_Struct) || (mCurTypeDef->mTypeCode == BfTypeCode_Enum)) && (!mCurTypeDef->mIsStatic); bool needsEqualsMethod = ((mCurTypeDef->mTypeCode == BfTypeCode_Struct) || (mCurTypeDef->mTypeCode == BfTypeCode_Enum)) && (!mCurTypeDef->mIsStatic);
BfMethodDef* equalsOpMethod = NULL;
BfMethodDef* equalsMethod = NULL; BfMethodDef* equalsMethod = NULL;
BfMethodDef* strictEqualsMethod = NULL; BfMethodDef* strictEqualsMethod = NULL;
@ -2038,6 +2026,10 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
{ {
if (method->mName == BF_METHODNAME_MARKMEMBERS_STATIC) if (method->mName == BF_METHODNAME_MARKMEMBERS_STATIC)
_SetMethod(staticMarkMethod, method); _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 else
{ {
@ -2061,7 +2053,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
if ((method->mParams[0]->mTypeRef->ToString() == mCurTypeDef->mName->ToString()) && if ((method->mParams[0]->mTypeRef->ToString() == mCurTypeDef->mName->ToString()) &&
(method->mParams[1]->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; methodDef->mAddedAfterEmit = mIsComptime;
} }
if ((needsEqualsMethod) && (equalsMethod == NULL)) if ((needsEqualsMethod) && (equalsMethod == NULL) && (equalsOpMethod == NULL))
{ {
auto methodDef = new BfMethodDef(); auto methodDef = new BfMethodDef();
mCurTypeDef->mMethods.push_back(methodDef); mCurTypeDef->mMethods.push_back(methodDef);
@ -2314,7 +2306,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
methodDef->mAddedAfterEmit = mIsComptime; methodDef->mAddedAfterEmit = mIsComptime;
} }
if (needsEqualsMethod) if ((needsEqualsMethod) && (strictEqualsMethod == NULL))
{ {
auto methodDef = new BfMethodDef(); auto methodDef = new BfMethodDef();
mCurTypeDef->mMethods.push_back(methodDef); mCurTypeDef->mMethods.push_back(methodDef);

View file

@ -4248,6 +4248,14 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
mModule->PopulateType(startCheckType, BfPopulateType_BaseType); 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; String findName;
int varSkipCount = 0; int varSkipCount = 0;
if (fieldName.StartsWith('@')) if (fieldName.StartsWith('@'))
@ -4627,6 +4635,8 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
bool doAccessCheck = true; 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))) if ((mModule->mAttributeState != NULL) && (mModule->mAttributeState->mCustomAttributes != NULL) && (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mDisableObjectAccessChecksAttributeTypeDef)))
doAccessCheck = false; doAccessCheck = false;
@ -4853,7 +4863,7 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
} }
// Check for direct auto-property access // 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)) if (auto propertyDeclaration = BfNodeDynCast<BfPropertyDeclaration>(mPropDef->mFieldDeclaration))
{ {
@ -10104,19 +10114,22 @@ void BfExprEvaluator::Visit(BfTypeOfExpression* typeOfExpr)
bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifierNode* propName) 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); auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef);
BfType* type; BfType* type;
//
{
// 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)) if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeOfExpr->mTypeRef))
{ {
SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
type = mModule->ResolveTypeRefAllowUnboundGenerics(typeOfExpr->mTypeRef, BfPopulateType_Identity); type = mModule->ResolveTypeRefAllowUnboundGenerics(typeOfExpr->mTypeRef, BfPopulateType_Identity);
} }
else else
{ {
type = ResolveTypeRef(typeOfExpr->mTypeRef, BfPopulateType_Identity); type = ResolveTypeRef(typeOfExpr->mTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_IgnoreLookupError);
}
} }
if (type == NULL) if (type == NULL)
@ -10207,10 +10220,41 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie
{ {
bool isMin = memberName == "MinValue"; bool isMin = memberName == "MinValue";
BfType* checkType = typeInstance; BfType* checkType = type;
if (checkType->IsTypedPrimitive()) if (checkType->IsTypedPrimitive())
checkType = checkType->GetUnderlyingType(); 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()) if (checkType->IsPrimitiveType())
{ {
auto primType = (BfPrimitiveType*)checkType; 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 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 else
@ -11932,6 +11976,7 @@ void BfExprEvaluator::VisitLambdaBodies(BfAstNode* body, BfFieldDtorDeclaration*
while (fieldDtor != NULL) while (fieldDtor != NULL)
{ {
mModule->mCurMethodState->mLeftBlockUncond = false;
mModule->VisitChild(fieldDtor->mBody); mModule->VisitChild(fieldDtor->mBody);
fieldDtor = fieldDtor->mNextFieldDtor; fieldDtor = fieldDtor->mNextFieldDtor;
} }
@ -13829,6 +13874,9 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
mModule->Fail("Too many array dimensions, consider using a jagged array.", objCreateExpr); mModule->Fail("Too many array dimensions, consider using a jagged array.", objCreateExpr);
} }
if (arrayType == NULL)
return;
if (isAppendAlloc) if (isAppendAlloc)
arrayValue = BfTypedValue(mModule->AppendAllocFromType(resultType, BfIRValue(), 0, arraySize, (int)dimLengthVals.size(), isRawArrayAlloc, zeroMemory), arrayType); arrayValue = BfTypedValue(mModule->AppendAllocFromType(resultType, BfIRValue(), 0, arraySize, (int)dimLengthVals.size(), isRawArrayAlloc, zeroMemory), arrayType);
else else
@ -14790,7 +14838,15 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc,
if (unspecializedMethod == NULL) if (unspecializedMethod == NULL)
unspecializedMethod = mModule->GetRawMethodInstance(curTypeInst, methodDef); 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) if (specializedReturnType != NULL)
*overrideReturnType = specializedReturnType; *overrideReturnType = specializedReturnType;
} }
@ -18712,9 +18768,9 @@ void BfExprEvaluator::Visit(BfTupleExpression* tupleExpr)
for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++) for (int fieldIdx = 0; fieldIdx < (int)tupleType->mFieldInstances.size(); fieldIdx++)
{ {
BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx]; BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
++valueIdx;
if (fieldInstance->mResolvedType->IsValuelessType()) if (fieldInstance->mResolvedType->IsValuelessType())
continue; continue;
++valueIdx;
auto typedVal = typedValues[valueIdx]; auto typedVal = typedValues[valueIdx];
if (!typedVal) if (!typedVal)
{ {
@ -20404,6 +20460,65 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp
if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift)) if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
wantType = NULL; // Don't presume wantType = NULL; // Don't presume
wantType = mModule->FixIntUnknown(wantType); 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)); rightValue = mModule->CreateValueFromExpression(rightExpression, wantType, (BfEvalExprFlags)((mBfEvalExprFlags & BfEvalExprFlags_InheritFlags) | BfEvalExprFlags_NoCast));
if ((!leftValue) || (!rightValue)) if ((!leftValue) || (!rightValue))
return; return;
@ -20611,58 +20726,6 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
return; 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)) if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
{ {
forceLeftType = true; forceLeftType = true;

View file

@ -615,17 +615,7 @@ BfIRValue BfIRConstHolder::CreateConst(BfConstant* fromConst, BfIRConstHolder* f
else if (fromConst->mConstType == BfConstType_GlobalVar) else if (fromConst->mConstType == BfConstType_GlobalVar)
{ {
auto fromGlobalVar = (BfGlobalVar*)fromConst; auto fromGlobalVar = (BfGlobalVar*)fromConst;
auto constGV = mTempAlloc.Alloc<BfGlobalVar>(); return CreateGlobalVariableConstant(fromGlobalVar->mType, fromGlobalVar->mIsConst, fromGlobalVar->mLinkageType, fromGlobalVar->mInitializer, fromGlobalVar->mName, fromGlobalVar->mIsTLS);
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;
} }
else if (fromConst->mConstType == BfConstType_GEP32_2) else if (fromConst->mConstType == BfConstType_GEP32_2)
{ {
@ -1875,6 +1865,7 @@ void BfIRBuilder::ClearConstData()
mTempAlloc.Clear(); mTempAlloc.Clear();
mConstMemMap.Clear(); mConstMemMap.Clear();
mFunctionMap.Clear(); mFunctionMap.Clear();
mGlobalVarMap.Clear();
BF_ASSERT(mMethodTypeMap.GetCount() == 0); BF_ASSERT(mMethodTypeMap.GetCount() == 0);
BF_ASSERT(mTypeMap.GetCount() == 0); BF_ASSERT(mTypeMap.GetCount() == 0);
BF_ASSERT(mDITemporaryTypes.size() == 0); BF_ASSERT(mDITemporaryTypes.size() == 0);
@ -1889,6 +1880,7 @@ void BfIRBuilder::ClearNonConstData()
{ {
mMethodTypeMap.Clear(); mMethodTypeMap.Clear();
mFunctionMap.Clear(); mFunctionMap.Clear();
mGlobalVarMap.Clear();
mTypeMap.Clear(); mTypeMap.Clear();
mConstMemMap.Clear(); mConstMemMap.Clear();
mDITemporaryTypes.Clear(); mDITemporaryTypes.Clear();
@ -2996,11 +2988,6 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
if (fieldInstance->mConstIdx != -1) if (fieldInstance->mConstIdx != -1)
{ {
if (fieldInstance->GetFieldDef()->mName == "mMembers")
{
NOP;
}
constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx); constant = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx);
staticValue = mModule->ConstantToCurrent(constant, typeInstance->mConstHolder, resolvedFieldType); staticValue = mModule->ConstantToCurrent(constant, typeInstance->mConstHolder, resolvedFieldType);
} }
@ -4743,8 +4730,30 @@ BfIRValue BfIRBuilder::CreateStackRestore(BfIRValue stackVal)
return retVal; 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); BF_ASSERT(varType);
auto constGV = mTempAlloc.Alloc<BfGlobalVar>(); auto constGV = mTempAlloc.Alloc<BfGlobalVar>();
@ -4758,23 +4767,15 @@ BfIRValue BfIRBuilder::CreateGlobalVariable(BfIRType varType, bool isConstant, B
constGV->mName = AllocStr(name); constGV->mName = AllocStr(name);
constGV->mIsTLS = isTLS; constGV->mIsTLS = isTLS;
if (!mIgnoreWrites) auto irValue = BfIRValue(BfIRValueFlags_Const, chunkId);;
{ *valuePtr = irValue;
if (initializer) return irValue;
mHasGlobalDefs = true; }
BfIRValue retVal = WriteCmd(BfIRCmd_GlobalVariable, varType, isConstant, (uint8)linkageType, name, isTLS, initializer); BfIRValue BfIRBuilder::CreateGlobalVariable(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS)
constGV->mStreamId = retVal.mId; {
retVal.mFlags = BfIRValueFlags_Const; auto irValue = CreateGlobalVariableConstant(varType, isConstant, linkageType, initializer, name, isTLS);
#ifdef CHECK_CONSTHOLDER CreateGlobalVariable(irValue);
retVal.mHolder = this;
#endif
retVal.mId = chunkId;
NEW_CMD_INSERTED_IRVALUE;
return retVal;
}
auto irValue = BfIRValue(BfIRValueFlags_Const, chunkId);
return irValue; return irValue;
} }

View file

@ -901,6 +901,7 @@ class BfIRConstHolder
public: public:
BumpAllocatorT<256> mTempAlloc; BumpAllocatorT<256> mTempAlloc;
BfModule* mModule; BfModule* mModule;
Dictionary<String, BfIRValue> mGlobalVarMap;
public: public:
void FixTypeCode(BfTypeCode& typeCode); void FixTypeCode(BfTypeCode& typeCode);
@ -936,6 +937,7 @@ public:
BfIRValue CreateTypeOf(BfType* type); BfIRValue CreateTypeOf(BfType* type);
BfIRValue CreateTypeOf(BfType* type, BfIRValue typeData); BfIRValue CreateTypeOf(BfType* type, BfIRValue typeData);
BfIRValue GetUndefConstValue(BfIRType type); 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); bool WriteConstant(BfIRValue val, void* ptr, BfType* type);
BfIRValue ReadConstant(void* ptr, BfType* type); BfIRValue ReadConstant(void* ptr, BfType* type);
@ -1227,6 +1229,7 @@ public:
BfIRValue CreateStackRestore(BfIRValue stackVal); BfIRValue CreateStackRestore(BfIRValue stackVal);
BfIRValue CreateGlobalVariable(BfIRType varType, bool isConstant, BfIRLinkageType linkageType, BfIRValue initializer, const StringImpl& name, bool isTLS = false); 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_SetUnnamedAddr(BfIRValue val, bool unnamedAddr);
void GlobalVar_SetInitializer(BfIRValue globalVar, BfIRValue initVal); void GlobalVar_SetInitializer(BfIRValue globalVar, BfIRValue initVal);
void GlobalVar_SetAlignment(BfIRValue globalVar, int alignment); void GlobalVar_SetAlignment(BfIRValue globalVar, int alignment);

View file

@ -809,6 +809,9 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry,
llvm::GlobalVariable* globalVariable = mLLVMModule->getGlobalVariable(name.c_str(), true); llvm::GlobalVariable* globalVariable = mLLVMModule->getGlobalVariable(name.c_str(), true);
if (globalVariable == NULL) if (globalVariable == NULL)
{
globalVariable = mLLVMModule->getGlobalVariable(name.c_str());
if (globalVariable == NULL)
{ {
globalVariable = new llvm::GlobalVariable( globalVariable = new llvm::GlobalVariable(
*mLLVMModule, *mLLVMModule,
@ -818,6 +821,7 @@ void BfIRCodeGen::Read(llvm::Value*& llvmValue, BfIRCodeGenEntry** codeGenEntry,
initializer, initializer,
name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal); name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal);
} }
}
llvmValue = globalVariable; llvmValue = globalVariable;
SetResult(streamId, globalVariable); SetResult(streamId, globalVariable);
@ -2389,13 +2393,17 @@ void BfIRCodeGen::HandleNextCmd()
CMD_PARAM(bool, isTLS); CMD_PARAM(bool, isTLS);
CMD_PARAM(llvm::Constant*, initializer); CMD_PARAM(llvm::Constant*, initializer);
auto globalVariable = new llvm::GlobalVariable( auto globalVariable = mLLVMModule->getGlobalVariable(name.c_str());
if (globalVariable == NULL)
{
globalVariable = new llvm::GlobalVariable(
*mLLVMModule, *mLLVMModule,
varType, varType,
isConstant, isConstant,
LLVMMapLinkageType(linkageType), LLVMMapLinkageType(linkageType),
initializer, initializer,
name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal); name.c_str(), NULL, isTLS ? llvm::GlobalValue::GeneralDynamicTLSModel : llvm::GlobalValue::NotThreadLocal);
}
SetResult(curId, globalVariable); SetResult(curId, globalVariable);
} }
break; 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 // 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 if (rebuildKind != BfModule::RebuildKind_None) // Leave string pool refs for when we need to use things like [LinkName("")] methods bofore re-reification
{
mStringPoolRefs.Clear(); mStringPoolRefs.Clear();
mUnreifiedStringPoolRefs.Clear();
}
mDllImportEntries.Clear(); mDllImportEntries.Clear();
mImportFileNames.Clear(); mImportFileNames.Clear();
for (auto& pairVal : mDeferredMethodCallData) for (auto& pairVal : mDeferredMethodCallData)
@ -1654,8 +1657,14 @@ String* BfModule::GetStringPoolString(BfIRValue constantStr, BfIRConstHolder * c
return NULL; 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; BfIRValue* irValue = NULL;
if (!mStringCharPtrPool.TryAdd(stringId, NULL, &irValue)) if (!mStringCharPtrPool.TryAdd(stringId, NULL, &irValue))
return *irValue; return *irValue;
@ -1670,13 +1679,13 @@ BfIRValue BfModule::GetStringCharPtr(int stringId)
return strCharPtrConst; return strCharPtrConst;
} }
BfIRValue BfModule::GetStringCharPtr(BfIRValue strValue) BfIRValue BfModule::GetStringCharPtr(BfIRValue strValue, bool force)
{ {
if (strValue.IsConst()) if (strValue.IsConst())
{ {
int stringId = GetStringPoolIdx(strValue); int stringId = GetStringPoolIdx(strValue);
BF_ASSERT(stringId != -1); BF_ASSERT(stringId != -1);
return GetStringCharPtr(stringId); return GetStringCharPtr(stringId, force);
} }
BfIRValue charPtrPtr = mBfIRBuilder->CreateInBoundsGEP(strValue, 0, 1); BfIRValue charPtrPtr = mBfIRBuilder->CreateInBoundsGEP(strValue, 0, 1);
@ -1684,28 +1693,34 @@ BfIRValue BfModule::GetStringCharPtr(BfIRValue strValue)
return charPtr; 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; BfIRValue* objValue;
if (mStringObjectPool.TryGetValue(strId, &objValue)) if (mStringObjectPool.TryGetValue(strId, &objValue))
return *objValue; return *objValue;
auto stringPoolEntry = mContext->mStringObjectIdMap[strId]; 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); auto stringType = ResolveTypeDef(mCompiler->mStringTypeDef, define ? BfPopulateType_Data : BfPopulateType_Declaration);
mBfIRBuilder->PopulateType(stringType); mBfIRBuilder->PopulateType(stringType);
int strId = mContext->GetStringLiteralId(str); int strId = mContext->GetStringLiteralId(str);
if ((mBfIRBuilder->mIgnoreWrites) && (!force))
{
mUnreifiedStringPoolRefs.Add(strId);
return mBfIRBuilder->CreateConst(BfTypeCode_StringId, strId);
}
BfIRValue* irValuePtr = NULL; BfIRValue* irValuePtr = NULL;
if (!mStringObjectPool.TryAdd(strId, NULL, &irValuePtr)) if (!mStringObjectPool.TryAdd(strId, NULL, &irValuePtr))
return *irValuePtr; return *irValuePtr;
@ -1916,13 +1931,7 @@ void BfModule::AddStackAlloc(BfTypedValue val, BfIRValue arraySize, BfAstNode* r
bool hadDtorCall = false; bool hadDtorCall = false;
while (checkBaseType != NULL) while (checkBaseType != NULL)
{ {
checkBaseType->mTypeDef->PopulateMemberSets(); BfMethodDef* dtorMethodDef = checkBaseType->mTypeDef->GetMethodByName("~this");
BfMemberSetEntry* entry = NULL;
BfMethodDef* dtorMethodDef = NULL;
checkBaseType->mTypeDef->mMethodSet.TryGetWith(String("~this"), &entry);
if (entry != NULL)
dtorMethodDef = (BfMethodDef*)entry->mMemberDef;
if (dtorMethodDef != NULL) if (dtorMethodDef != NULL)
{ {
auto dtorMethodInstance = GetMethodInstance(checkBaseType, dtorMethodDef, BfTypeVector()); auto dtorMethodInstance = GetMethodInstance(checkBaseType, dtorMethodDef, BfTypeVector());
@ -3416,10 +3425,11 @@ void BfModule::AddDependency(BfType* usedType, BfType* userType, BfDependencyMap
BfModule* usedModule; BfModule* usedModule;
if (usedType->IsFunction()) if (usedType->IsFunction())
{ {
auto typeInst = usedType->ToTypeInstance(); if (mCompiler->mFunctionTypeDef != NULL)
if (typeInst->mBaseType == NULL) {
PopulateType(typeInst); auto functionType = ResolveTypeDef(mCompiler->mFunctionTypeDef)->ToTypeInstance();
usedModule = typeInst->mBaseType->GetModule(); usedModule = functionType->GetModule();
}
} }
else else
usedModule = usedType->GetModule(); usedModule = usedType->GetModule();
@ -5235,7 +5245,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
typeFlags |= BfTypeFlags_Delegate; typeFlags |= BfTypeFlags_Delegate;
if (type->IsFunction()) if (type->IsFunction())
typeFlags |= BfTypeFlags_Function; typeFlags |= BfTypeFlags_Function;
if (type->WantsGCMarking()) if ((type->mDefineState != BfTypeDefineState_CETypeInit) && (type->WantsGCMarking()))
typeFlags |= BfTypeFlags_WantsMarking; typeFlags |= BfTypeFlags_WantsMarking;
int virtSlotIdx = -1; int virtSlotIdx = -1;
@ -5906,8 +5916,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
if (needsTypeNames) if (needsTypeNames)
{ {
typeNameConst = GetStringObjectValue(typeDef->mName->mString, true); typeNameConst = GetStringObjectValue(typeDef->mName->mString, !mIsComptimeModule);
namespaceConst = GetStringObjectValue(typeDef->mNamespace.ToString(), true); namespaceConst = GetStringObjectValue(typeDef->mNamespace.ToString(), !mIsComptimeModule);
} }
else else
{ {
@ -6023,7 +6033,28 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
PUSH_INT16(0); // mSize PUSH_INT16(0); // mSize
PUSH_INT32(attr->mType->mTypeId); // mType 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); auto ctorMethodInstance = GetRawMethodInstanceAtIdx(attr->mType, attr->mCtor->mIdx);
int argIdx = 0; int argIdx = 0;
@ -6047,7 +6078,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
*orderedIdPtr = (int)usedStringIdMap.size() - 1; *orderedIdPtr = (int)usedStringIdMap.size() - 1;
} }
GetStringObjectValue(stringId); GetStringObjectValue(stringId, true, true);
PUSH_INT8(0xFF); // String PUSH_INT8(0xFF); // String
PUSH_INT32(*orderedIdPtr); PUSH_INT32(*orderedIdPtr);
argIdx++; argIdx++;
@ -6067,7 +6098,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
*orderedIdPtr = (int)usedStringIdMap.size() - 1; *orderedIdPtr = (int)usedStringIdMap.size() - 1;
} }
GetStringObjectValue(stringId); GetStringObjectValue(stringId, true, true);
PUSH_INT8(0xFF); // String PUSH_INT8(0xFF); // String
PUSH_INT32(*orderedIdPtr); PUSH_INT32(*orderedIdPtr);
argIdx++; argIdx++;
@ -6231,7 +6262,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
BfType* payloadType = typeInstance->GetUnionInnerType(); BfType* payloadType = typeInstance->GetUnionInnerType();
if (!payloadType->IsValuelessType()) if (!payloadType->IsValuelessType())
{ {
BfIRValue payloadNameConst = GetStringObjectValue("$payload", true); BfIRValue payloadNameConst = GetStringObjectValue("$payload", !mIsComptimeModule);
SizedArray<BfIRValue, 8> payloadFieldVals = SizedArray<BfIRValue, 8> payloadFieldVals =
{ {
emptyValueType, emptyValueType,
@ -6246,7 +6277,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
} }
BfType* dscrType = typeInstance->GetDiscriminatorType(); BfType* dscrType = typeInstance->GetDiscriminatorType();
BfIRValue dscrNameConst = GetStringObjectValue("$discriminator", true); BfIRValue dscrNameConst = GetStringObjectValue("$discriminator", !mIsComptimeModule);
SizedArray<BfIRValue, 8> dscrFieldVals = SizedArray<BfIRValue, 8> dscrFieldVals =
{ {
emptyValueType, emptyValueType,
@ -6268,7 +6299,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
BfFieldInstance* fieldInstance = &typeInstance->mFieldInstances[fieldIdx]; BfFieldInstance* fieldInstance = &typeInstance->mFieldInstances[fieldIdx];
BfFieldDef* fieldDef = fieldInstance->GetFieldDef(); BfFieldDef* fieldDef = fieldInstance->GetFieldDef();
BfIRValue fieldNameConst = GetStringObjectValue(fieldDef->mName, true); BfIRValue fieldNameConst = GetStringObjectValue(fieldDef->mName, !mIsComptimeModule);
int typeId = 0; int typeId = 0;
auto fieldType = fieldInstance->GetResolvedType(); auto fieldType = fieldInstance->GetResolvedType();
@ -6448,6 +6479,14 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
BfType* reflectParamDataType = ResolveTypeDef(mCompiler->mReflectParamDataDef); BfType* reflectParamDataType = ResolveTypeDef(mCompiler->mReflectParamDataDef);
BfType* reflectParamDataPtrType = CreatePointerType(reflectParamDataType); BfType* reflectParamDataPtrType = CreatePointerType(reflectParamDataType);
struct _SortedMethodInfo
{
BfMethodDef* mMethodDef;
BfCustomAttributes* mMethodCustomAttributes;
};
Array<_SortedMethodInfo> sortedMethodList;
SizedArray<BfIRValue, 16> methodTypes; SizedArray<BfIRValue, 16> methodTypes;
for (int methodIdx = 0; methodIdx < (int)typeDef->mMethods.size(); methodIdx++) 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) if (!includeMethod)
continue; 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; BfModuleMethodInstance moduleMethodInstance;
BfIRValue funcVal = voidPtrNull; BfIRValue funcVal = voidPtrNull;
@ -6544,11 +6612,11 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
funcVal = mBfIRBuilder->CreateBitCast(moduleMethodInstance.mFunc, voidPtrIRType); funcVal = mBfIRBuilder->CreateBitCast(moduleMethodInstance.mFunc, voidPtrIRType);
} }
BfIRValue methodNameConst = GetStringObjectValue(methodDef->mName, true); BfIRValue methodNameConst = GetStringObjectValue(methodDef->mName, !mIsComptimeModule);
BfMethodFlags methodFlags = defaultMethod->GetMethodFlags(); BfMethodFlags methodFlags = defaultMethod->GetMethodFlags();
int customAttrIdx = _HandleCustomAttrs(methodCustomAttributes); int customAttrIdx = _HandleCustomAttrs(methodInfo.mMethodCustomAttributes);
enum ParamFlags enum ParamFlags
{ {
@ -6567,7 +6635,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
if (defaultMethod->GetParamIsSplat(paramIdx)) if (defaultMethod->GetParamIsSplat(paramIdx))
paramFlags = (ParamFlags)(paramFlags | ParamFlag_Splat); paramFlags = (ParamFlags)(paramFlags | ParamFlag_Splat);
BfIRValue paramNameConst = GetStringObjectValue(paramName, true); BfIRValue paramNameConst = GetStringObjectValue(paramName, !mIsComptimeModule);
SizedArray<BfIRValue, 8> paramDataVals = SizedArray<BfIRValue, 8> paramDataVals =
{ {
@ -7150,7 +7218,7 @@ BfIRFunction BfModule::GetBuiltInFunc(BfBuiltInFuncType funcTypeId)
return mBuiltInFuncs[(int)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(); BfGenericParamDef* genericParamDef = genericParamInstance->GetGenericParamDef();
BfExternalConstraintDef* externConstraintDef = genericParamInstance->GetExternConstraintDef(); BfExternalConstraintDef* externConstraintDef = genericParamInstance->GetExternConstraintDef();
@ -7256,14 +7324,23 @@ void BfModule::ResolveGenericParamConstraints(BfGenericParamInstance* genericPar
if (bfAutocomplete != NULL) if (bfAutocomplete != NULL)
bfAutocomplete->CheckTypeRef(constraintTypeRef, true); bfAutocomplete->CheckTypeRef(constraintTypeRef, true);
//TODO: Constraints may refer to other generic params (of either type or method) //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; BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_AllowGenericMethodParamConstValue;
if (isUnspecialized) if (isUnspecialized)
resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_DisallowComptime); 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 (constraintType != NULL)
{ {
if (deferredResolveTypes != NULL)
{
PopulateType(constraintType, BfPopulateType_Declaration);
if (constraintType->IsUnspecializedTypeVariation())
deferredResolveTypes->Add(constraintTypeRef);
}
if ((constraintDef->mGenericParamFlags & BfGenericParamFlag_Const) != 0) if ((constraintDef->mGenericParamFlags & BfGenericParamFlag_Const) != 0)
{ {
bool isValidTypeCode = false; bool isValidTypeCode = false;
@ -7448,7 +7525,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
int checkGenericParamFlags = 0; int checkGenericParamFlags = 0;
if (checkArgType->IsGenericParam()) if (checkArgType->IsGenericParam())
{ {
auto checkGenericParamInst = GetGenericParamInstance((BfGenericParamType*)checkArgType); BfGenericParamInstance* checkGenericParamInst = GetGenericParamInstance((BfGenericParamType*)checkArgType);
checkGenericParamFlags = checkGenericParamInst->mGenericParamFlags; checkGenericParamFlags = checkGenericParamInst->mGenericParamFlags;
if (checkGenericParamInst->mTypeConstraint != NULL) if (checkGenericParamInst->mTypeConstraint != NULL)
checkArgType = checkGenericParamInst->mTypeConstraint; checkArgType = checkGenericParamInst->mTypeConstraint;
@ -10601,6 +10678,7 @@ void BfModule::ClearConstData()
mStringObjectPool.Clear(); mStringObjectPool.Clear();
mStringCharPtrPool.Clear(); mStringCharPtrPool.Clear();
mStringPoolRefs.Clear(); mStringPoolRefs.Clear();
mUnreifiedStringPoolRefs.Clear();
} }
BfTypedValue BfModule::GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType) 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); auto constVal = mBfIRBuilder->CreateConst(constant, constHolder);
BfTypedValue typedValue; BfTypedValue typedValue;
bool allowUnactualized = mBfIRBuilder->mIgnoreWrites;
if (constant->mTypeCode == BfTypeCode_StringId) if (constant->mTypeCode == BfTypeCode_StringId)
{ {
if ((wantType->IsInstanceOf(mCompiler->mStringTypeDef)) || if ((wantType->IsInstanceOf(mCompiler->mStringTypeDef)) ||
((wantType->IsPointer()) && (wantType->GetUnderlyingType() == GetPrimitiveType(BfTypeCode_Char8)))) ((wantType->IsPointer()) && (wantType->GetUnderlyingType() == GetPrimitiveType(BfTypeCode_Char8))))
{ {
typedValue = BfTypedValue(ConstantToCurrent(constant, constHolder, wantType), wantType); typedValue = BfTypedValue(ConstantToCurrent(constant, constHolder, wantType, allowUnactualized), wantType);
return typedValue; return typedValue;
} }
auto stringType = ResolveTypeDef(mCompiler->mStringTypeDef); auto stringType = ResolveTypeDef(mCompiler->mStringTypeDef);
typedValue = BfTypedValue(ConstantToCurrent(constant, constHolder, stringType), stringType); typedValue = BfTypedValue(ConstantToCurrent(constant, constHolder, stringType, allowUnactualized), stringType);
} }
if (!typedValue) if (!typedValue)
@ -10684,7 +10763,27 @@ BfTypedValue BfModule::GetTypedValueFromConstant(BfConstant* constant, BfIRConst
return BfTypedValue(irValue, wantType, false); 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) if (constant->mTypeCode == BfTypeCode_NullPtr)
{ {
@ -10699,20 +10798,27 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con
if (constant->mTypeCode == BfTypeCode_StringId) if (constant->mTypeCode == BfTypeCode_StringId)
{ {
if (!allowStringId) if (!allowUnactualized)
{ {
if ((wantType->IsInstanceOf(mCompiler->mStringTypeDef)) || if ((wantType->IsInstanceOf(mCompiler->mStringTypeDef)) ||
((wantType->IsPointer()) && (wantType->GetUnderlyingType() == GetPrimitiveType(BfTypeCode_Char8)))) ((wantType->IsPointer()) && (wantType->GetUnderlyingType() == GetPrimitiveType(BfTypeCode_Char8))))
{ {
const StringImpl& str = mContext->mStringObjectIdMap[constant->mInt32].mString; const StringImpl& str = mContext->mStringObjectIdMap[constant->mInt32].mString;
BfIRValue stringObjConst = GetStringObjectValue(str); BfIRValue stringObjConst = GetStringObjectValue(str, false, true);
if (wantType->IsPointer()) if (wantType->IsPointer())
return GetStringCharPtr(stringObjConst); return GetStringCharPtr(stringObjConst, true);
return stringObjConst; 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) if (constant->mConstType == BfConstType_Agg)
{ {
auto constArray = (BfConstantAgg*)constant; 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) void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrTarget, bool allowNonConstArgs, BfCaptureInfo* captureInfo)
{ {
if (!mCompiler->mHasRequiredTypes)
return;
if ((attributesDirective != NULL) && (mCompiler->mResolvePassData != NULL) && if ((attributesDirective != NULL) && (mCompiler->mResolvePassData != NULL) &&
(attributesDirective->IsFromParser(mCompiler->mResolvePassData->mParser)) && (mCompiler->mResolvePassData->mSourceClassifier != NULL)) (attributesDirective->IsFromParser(mCompiler->mResolvePassData->mParser)) && (mCompiler->mResolvePassData->mSourceClassifier != NULL))
{ {
@ -10908,6 +11017,12 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
continue; continue;
} }
if ((mIsReified) && (attrTypeInst->mAttributeData != NULL) && ((attrTypeInst->mAttributeData->mFlags & BfAttributeFlag_ReflectAttribute) != 0))
{
// Reify attribute
PopulateType(attrTypeInst);
}
if (mCurTypeInstance != NULL) if (mCurTypeInstance != NULL)
AddDependency(attrTypeInst, mCurTypeInstance, BfDependencyMap::DependencyFlag_CustomAttribute); AddDependency(attrTypeInst, mCurTypeInstance, BfDependencyMap::DependencyFlag_CustomAttribute);
@ -11019,7 +11134,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
auto& fieldTypeInst = checkTypeInst->mFieldInstances[bestField->mIdx]; auto& fieldTypeInst = checkTypeInst->mFieldInstances[bestField->mIdx];
if (assignExpr->mRight != NULL) if (assignExpr->mRight != NULL)
{ {
BfTypedValue result = constResolver.Resolve(assignExpr->mRight, fieldTypeInst.mResolvedType); BfTypedValue result = constResolver.Resolve(assignExpr->mRight, fieldTypeInst.mResolvedType, BfConstResolveFlag_NoActualizeValues);
if (result) if (result)
{ {
CurrentAddToConstHolder(result.mValue); CurrentAddToConstHolder(result.mValue);
@ -11078,9 +11193,11 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
auto propType = methodInstance.mMethodInstance->GetParamType(0); auto propType = methodInstance.mMethodInstance->GetParamType(0);
if (assignExpr->mRight != NULL) if (assignExpr->mRight != NULL)
{ {
BfTypedValue result = constResolver.Resolve(assignExpr->mRight, propType); BfTypedValue result = constResolver.Resolve(assignExpr->mRight, propType, BfConstResolveFlag_NoActualizeValues);
if (result) if ((result) && (!result.mType->IsVar()))
{ {
if (!result.mValue.IsConst())
result = GetDefaultTypedValue(result.mType);
BF_ASSERT(result.mType == propType); BF_ASSERT(result.mType == propType);
CurrentAddToConstHolder(result.mValue); CurrentAddToConstHolder(result.mValue);
setProperty.mParam = result; setProperty.mParam = result;
@ -11092,7 +11209,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
} }
if ((!handledExpr) && (assignExpr->mRight != NULL)) if ((!handledExpr) && (assignExpr->mRight != NULL))
constResolver.Resolve(assignExpr->mRight); constResolver.Resolve(assignExpr->mRight, NULL, BfConstResolveFlag_NoActualizeValues);
} }
else else
{ {
@ -11112,7 +11229,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
resolvedArg.mArgFlags = BfArgFlag_DeferredEval; resolvedArg.mArgFlags = BfArgFlag_DeferredEval;
} }
else else
resolvedArg.mTypedValue = constResolver.Resolve(arg); resolvedArg.mTypedValue = constResolver.Resolve(arg, NULL, BfConstResolveFlag_NoActualizeValues);
if (!inPropSet) if (!inPropSet)
{ {
@ -11193,7 +11310,7 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
if ((arg.mArgFlags & BfArgFlag_DeferredEval) != 0) if ((arg.mArgFlags & BfArgFlag_DeferredEval) != 0)
{ {
if (auto expr = BfNodeDynCast<BfExpression>(arg.mExpression)) 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_UIntPtr:
case BfTypeCode_IntUnknown: case BfTypeCode_IntUnknown:
case BfTypeCode_UIntUnknown: case BfTypeCode_UIntUnknown:
case BfTypeCode_Float:
case BfTypeCode_Double: case BfTypeCode_Double:
case BfTypeCode_Char8: case BfTypeCode_Char8:
case BfTypeCode_Char16: case BfTypeCode_Char16:
@ -11520,6 +11636,10 @@ BfVariant BfModule::TypedValueToVariant(BfAstNode* refNode, const BfTypedValue&
variant.mTypeCode = constant->mTypeCode; variant.mTypeCode = constant->mTypeCode;
variant.mInt64 = constant->mInt64; variant.mInt64 = constant->mInt64;
break; break;
case BfTypeCode_Float:
variant.mTypeCode = constant->mTypeCode;
variant.mSingle = (float)constant->mDouble;
break;
default: default:
if (refNode != NULL) if (refNode != NULL)
Fail("Invalid const expression type", refNode); Fail("Invalid const expression type", refNode);
@ -13624,6 +13744,13 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance)
{ {
globalValue = *globalValuePtr; globalValue = *globalValuePtr;
BF_ASSERT(globalValue); BF_ASSERT(globalValue);
auto globalVar = (BfGlobalVar*)mBfIRBuilder->GetConstant(globalValue);
if ((globalVar->mStreamId == -1) && (!mBfIRBuilder->mIgnoreWrites))
{
mBfIRBuilder->MapType(fieldInstance->mResolvedType);
mBfIRBuilder->CreateGlobalVariable(globalValue);
}
} }
else else
{ {
@ -13656,15 +13783,10 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance)
staticVarName, staticVarName,
IsThreadLocal(fieldInstance)); IsThreadLocal(fieldInstance));
if (!mBfIRBuilder->mIgnoreWrites)
{
// Only store this if we actually did the creation
BF_ASSERT(globalValue); BF_ASSERT(globalValue);
mStaticFieldRefs[fieldInstance] = globalValue; mStaticFieldRefs[fieldInstance] = globalValue;
}
BfLogSysM("Mod:%p Type:%p ReferenceStaticField %p -> %p\n", this, fieldInstance->mOwner, 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(); 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' // Check mixin state for 'this'
{ {
auto checkMethodState = mCurMethodState; auto checkMethodState = mCurMethodState;
@ -14060,7 +14155,9 @@ void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, bool doAli
{ {
if ((isConstant) && (!didConstToMem)) 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 else
{ {
@ -15668,7 +15765,11 @@ void BfModule::EmitDtorBody()
} }
else else
{ {
if (!mCurTypeInstance->IsValueType()) if (fieldInst->mResolvedType->IsValuelessType())
{
value = mBfIRBuilder->GetFakeVal();
}
else if (!mCurTypeInstance->IsValueType())
{ {
auto thisValue = GetThis(); auto thisValue = GetThis();
value = mBfIRBuilder->CreateInBoundsGEP(thisValue.mValue, 0, fieldInst->mDataIdx); value = mBfIRBuilder->CreateInBoundsGEP(thisValue.mValue, 0, fieldInst->mDataIdx);
@ -15744,13 +15845,7 @@ void BfModule::EmitDtorBody()
UpdateSrcPos(typeDef->mTypeDeclaration->mNameNode); UpdateSrcPos(typeDef->mTypeDeclaration->mNameNode);
} }
checkBaseType->mTypeDef->PopulateMemberSets(); BfMethodDef* dtorMethodDef = checkBaseType->mTypeDef->GetMethodByName("~this");
BfMemberSetEntry* entry = NULL;
BfMethodDef* dtorMethodDef = NULL;
checkBaseType->mTypeDef->mMethodSet.TryGetWith(String("~this"), &entry);
if (entry != NULL)
dtorMethodDef = (BfMethodDef*)entry->mMemberDef;
if (dtorMethodDef != NULL) if (dtorMethodDef != NULL)
{ {
auto dtorMethodInstance = GetMethodInstance(checkBaseType, dtorMethodDef, BfTypeVector()); 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); 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 (methodInstance->GetImportCallKind() != BfImportCallKind_None)
{ {
if (mBfIRBuilder->mIgnoreWrites) if (mBfIRBuilder->mIgnoreWrites)
@ -19451,7 +19575,11 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
} }
auto bodyBlock = BfNodeDynCast<BfBlock>(methodDef->mBody); 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) if (methodDeclaration != NULL)
{ {
@ -19463,34 +19591,19 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
} }
bool isDllImport = false; 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]; mImportFileNames.Add(importStrNum);
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 }
} }
else if (methodInstance->GetImportKind() == BfImportKind_Import_Dynamic) else if (methodInstance->GetImportKind() == BfImportKind_Import_Dynamic)
{ {
@ -21534,6 +21647,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
{ {
BfTypeInstance* unspecializedTypeInstance = NULL; BfTypeInstance* unspecializedTypeInstance = NULL;
Array<BfTypeReference*> deferredResolveTypes;
for (int genericParamIdx = 0; genericParamIdx < (int)methodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++) for (int genericParamIdx = 0; genericParamIdx < (int)methodInstance->mMethodInfoEx->mGenericParams.size(); genericParamIdx++)
{ {
auto genericParam = methodInstance->mMethodInfoEx->mGenericParams[genericParamIdx]; auto genericParam = methodInstance->mMethodInfoEx->mGenericParams[genericParamIdx];
@ -21558,7 +21672,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var); genericParam->mExternType = GetPrimitiveType(BfTypeCode_Var);
} }
ResolveGenericParamConstraints(genericParam, methodInstance->mIsUnspecialized); ResolveGenericParamConstraints(genericParam, methodInstance->mIsUnspecialized, &deferredResolveTypes);
if (genericParamIdx < (int)methodDef->mGenericParams.size()) 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) for (auto genericParam : methodInstance->mMethodInfoEx->mGenericParams)
{ {
@ -21920,6 +22036,12 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
} }
else else
{ {
BfTypeState typeState;
typeState.mTypeInstance = mCurTypeInstance;
typeState.mCurTypeDef = methodDef->mDeclaringType;
//typeState.mCurMethodDef = methodDef;
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
BfConstResolver constResolver(this); BfConstResolver constResolver(this);
defaultValue = constResolver.Resolve(paramDef->mParamDeclaration->mInitializer, resolvedParamType, (BfConstResolveFlags)(BfConstResolveFlag_NoCast | BfConstResolveFlag_AllowGlobalVariable)); defaultValue = constResolver.Resolve(paramDef->mParamDeclaration->mInitializer, resolvedParamType, (BfConstResolveFlags)(BfConstResolveFlag_NoCast | BfConstResolveFlag_AllowGlobalVariable));
if ((defaultValue) && (defaultValue.mType != resolvedParamType)) if ((defaultValue) && (defaultValue.mType != resolvedParamType))
@ -22051,7 +22173,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
resolvedParamType = CreateArrayType(mContext->mBfObjectType, 1); resolvedParamType = CreateArrayType(mContext->mBfObjectType, 1);
} }
if (addParams) if ((addParams) && (resolvedParamType != NULL))
{ {
BfMethodParam methodParam; BfMethodParam methodParam;
methodParam.mResolvedType = resolvedParamType; 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 ((methodDef->mIsVirtual) && (methodDef->mIsStatic) && (!methodInstance->mIsInnerOverride))
{ {
if ((virtualToken != NULL) && (virtualToken->mToken == BfToken_Override) && (methodDef->mDeclaringType->mTypeCode == BfTypeCode_Extension)) 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> mStringObjectPool;
Dictionary<int, BfIRValue> mStringCharPtrPool; Dictionary<int, BfIRValue> mStringCharPtrPool;
Array<int> mStringPoolRefs; Array<int> mStringPoolRefs;
HashSet<int> mUnreifiedStringPoolRefs;
Array<BfIRBuilder*> mPrevIRBuilders; // Before extensions Array<BfIRBuilder*> mPrevIRBuilders; // Before extensions
BfIRBuilder* mBfIRBuilder; BfIRBuilder* mBfIRBuilder;
@ -1538,11 +1539,11 @@ public:
BfIRValue CreateStringCharPtr(const StringImpl& str, int stringId, bool define); BfIRValue CreateStringCharPtr(const StringImpl& str, int stringId, bool define);
int GetStringPoolIdx(BfIRValue constantStr, BfIRConstHolder* constHolder = NULL); int GetStringPoolIdx(BfIRValue constantStr, BfIRConstHolder* constHolder = NULL);
String* GetStringPoolString(BfIRValue constantStr, BfIRConstHolder* constHolder = NULL); String* GetStringPoolString(BfIRValue constantStr, BfIRConstHolder* constHolder = NULL);
BfIRValue GetStringCharPtr(int stringId); BfIRValue GetStringCharPtr(int stringId, bool force = false);
BfIRValue GetStringCharPtr(BfIRValue strValue); BfIRValue GetStringCharPtr(BfIRValue strValue, bool force = false);
BfIRValue GetStringCharPtr(const StringImpl& str); BfIRValue GetStringCharPtr(const StringImpl& str, bool force = false);
BfIRValue GetStringObjectValue(int idx); BfIRValue GetStringObjectValue(int idx, bool define, bool force);
BfIRValue GetStringObjectValue(const StringImpl& str, bool define = false); BfIRValue GetStringObjectValue(const StringImpl& str, bool define = false, bool force = false);
BfIRValue CreateGlobalConstValue(const StringImpl& name, BfIRValue constant, BfIRType type, bool external); BfIRValue CreateGlobalConstValue(const StringImpl& name, BfIRValue constant, BfIRType type, bool external);
void VariantToString(StringImpl& str, const BfVariant& variant); void VariantToString(StringImpl& str, const BfVariant& variant);
StringT<128> TypeToString(BfType* resolvedType, Array<String>* genericMethodParamNameOverrides = NULL); StringT<128> TypeToString(BfType* resolvedType, Array<String>* genericMethodParamNameOverrides = NULL);
@ -1553,8 +1554,9 @@ public:
void pm(BfMethodInstance* type); void pm(BfMethodInstance* type);
void CurrentAddToConstHolder(BfIRValue& irVal); void CurrentAddToConstHolder(BfIRValue& irVal);
void ClearConstData(); void ClearConstData();
bool HasUnactializedConstant(BfConstant* constant, BfIRConstHolder* constHolder);
BfTypedValue GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType); 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 ValidateCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeTargets attrTarget);
void GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs = false, BfCaptureInfo* captureInfo = NULL); 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); BfCustomAttributes* GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs = false, BfCaptureInfo* captureInfo = NULL);
@ -1772,11 +1774,11 @@ public:
BfType* FixIntUnknown(BfType* type); BfType* FixIntUnknown(BfType* type);
void FixIntUnknown(BfTypedValue& typedVal, BfType* matchType = NULL); void FixIntUnknown(BfTypedValue& typedVal, BfType* matchType = NULL);
void FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs); void FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs);
void FixValueActualization(BfTypedValue& typedVal); void FixValueActualization(BfTypedValue& typedVal, bool force = false);
bool TypeEquals(BfTypedValue& val, BfType* type); bool TypeEquals(BfTypedValue& val, BfType* type);
BfTypeDef* ResolveGenericInstanceDef(BfGenericInstanceTypeRef* genericTypeRef, BfType** outType = NULL, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None); BfTypeDef* ResolveGenericInstanceDef(BfGenericInstanceTypeRef* genericTypeRef, BfType** outType = NULL, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None);
BfType* ResolveType(BfType* lookupType, BfPopulateType populateType = BfPopulateType_Data, 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); String GenericParamSourceToString(const BfGenericParamSource& genericParamSource);
bool CheckGenericConstraints(const BfGenericParamSource& genericParamSource, BfType* checkArgType, BfAstNode* checkArgTypeRef, BfGenericParamInstance* genericParamInst, BfTypeVector* methodGenericArgs = NULL, BfError** errorOut = NULL); 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); 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.mResolveKind = BfTypeState::ResolveKind_BuildingGenericParams;
typeState.mTypeInstance = resolvedTypeRef->ToTypeInstance(); typeState.mTypeInstance = resolvedTypeRef->ToTypeInstance();
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState); SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
Array<BfTypeReference*> deferredResolveTypes;
BF_ASSERT(mCurMethodInstance == NULL); BF_ASSERT(mCurMethodInstance == NULL);
@ -210,7 +211,7 @@ bool BfModule::FinishGenericParams(BfType* resolvedTypeRef)
genericParamInstance->mExternType = GetPrimitiveType(BfTypeCode_Var); genericParamInstance->mExternType = GetPrimitiveType(BfTypeCode_Var);
} }
ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType()); ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType(), &deferredResolveTypes);
if (genericParamDef != NULL) if (genericParamDef != NULL)
{ {
@ -283,7 +284,7 @@ bool BfModule::FinishGenericParams(BfType* resolvedTypeRef)
genericParamInstance->mExternType = GetPrimitiveType(BfTypeCode_Var); genericParamInstance->mExternType = GetPrimitiveType(BfTypeCode_Var);
} }
ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType()); ResolveGenericParamConstraints(genericParamInstance, genericTypeInst->IsUnspecializedType(), &deferredResolveTypes);
auto genericParamDef = genericParamInstance->GetGenericParamDef(); auto genericParamDef = genericParamInstance->GetGenericParamDef();
if (genericParamDef != NULL) 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 genericParam : genericTypeInst->mGenericTypeInfo->mGenericParams)
{ {
for (auto constraintTypeInst : genericParam->mInterfaceConstraints) for (auto constraintTypeInst : genericParam->mInterfaceConstraints)
@ -339,6 +343,13 @@ bool BfModule::ValidateGenericConstraints(BfTypeReference* typeRef, BfTypeInstan
return true; 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; auto typeDef = genericTypeInst->mTypeDef;
for (int paramIdx = 0; paramIdx < (int)genericTypeInst->mGenericTypeInfo->mGenericParams.size(); paramIdx++) 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->mIsReified = true;
typeModule->mWantsIRIgnoreWrites = false; typeModule->mWantsIRIgnoreWrites = false;
for (auto ownedTypes : typeModule->mOwnedTypeInstances) for (auto ownedTypes : typeModule->mOwnedTypeInstances)
{
ownedTypes->mIsReified = true; 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++; mCompiler->mStats.mReifiedModuleCount++;
if (typeModule->mBfIRBuilder != NULL) if (typeModule->mBfIRBuilder != NULL)
{ {
@ -2002,7 +2027,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance*
for (auto& customAttribute : customAttributes->mAttributes) for (auto& customAttribute : customAttributes->mAttributes)
{ {
auto attrType = customAttribute.mType; auto attrType = customAttribute.mType;
PopulateType(attrType, BfPopulateType_DataAndMethods); mContext->mUnreifiedModule->PopulateType(attrType, BfPopulateType_DataAndMethods);
if (attrType->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted) if (attrType->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted)
continue; continue;
@ -2331,7 +2356,7 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance)
for (auto& customAttribute : customAttributes->mAttributes) for (auto& customAttribute : customAttributes->mAttributes)
{ {
auto attrType = customAttribute.mType; auto attrType = customAttribute.mType;
PopulateType(attrType, BfPopulateType_DataAndMethods); mContext->mUnreifiedModule->PopulateType(attrType, BfPopulateType_DataAndMethods);
if (attrType->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted) if (attrType->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted)
continue; continue;
@ -2599,8 +2624,10 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeInstance); SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeInstance);
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL); SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
SetAndRestoreValue<BfMethodState*> prevMethodState(mCurMethodState, 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); BfTypeState typeState(mCurTypeInstance, mContext->mCurTypeState);
typeState.mPopulateType = populateType; typeState.mPopulateType = populateType;
@ -2640,7 +2667,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
if (typeInstance->mIsFinishingType) if (typeInstance->mIsFinishingType)
{ {
// This type already failed if (typeInstance->mTypeFailed)
return; return;
} }
@ -3006,7 +3033,10 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
bool populateBase = !typeInstance->mTypeFailed; bool populateBase = !typeInstance->mTypeFailed;
auto checkType = ResolveTypeRef(checkTypeRef, BfPopulateType_Declaration); auto checkType = ResolveTypeRef(checkTypeRef, BfPopulateType_Declaration);
if ((checkType != NULL) && (!checkType->IsInterface()) && (populateBase)) if ((checkType != NULL) && (!checkType->IsInterface()) && (populateBase))
{
SetAndRestoreValue<BfTypeInstance*> prevBaseType(mContext->mCurTypeState->mCurBaseType, checkType->ToTypeInstance());
PopulateType(checkType, BfPopulateType_Data); PopulateType(checkType, BfPopulateType_Data);
}
if (typeInstance->mDefineState >= BfTypeDefineState_Defined) if (typeInstance->mDefineState >= BfTypeDefineState_Defined)
{ {
@ -3387,6 +3417,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
for (auto& validateEntry : deferredTypeValidateList) for (auto& validateEntry : deferredTypeValidateList)
{ {
SetAndRestoreValue<BfTypeReference*> prevAttributeTypeRef(typeState.mCurAttributeTypeRef, validateEntry.mTypeRef);
SetAndRestoreValue<bool> ignoreErrors(mIgnoreErrors, mIgnoreErrors | validateEntry.mIgnoreErrors); SetAndRestoreValue<bool> ignoreErrors(mIgnoreErrors, mIgnoreErrors | validateEntry.mIgnoreErrors);
ValidateGenericConstraints(validateEntry.mTypeRef, validateEntry.mGenericType, false); ValidateGenericConstraints(validateEntry.mTypeRef, validateEntry.mGenericType, false);
} }
@ -3742,6 +3773,11 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
if (populateChildType) if (populateChildType)
{ {
if (resolvedFieldType->IsFinishingType())
{
AssertErrorState();
}
else
BF_ASSERT(!resolvedFieldType->IsDataIncomplete()); BF_ASSERT(!resolvedFieldType->IsDataIncomplete());
} }
else else
@ -4318,6 +4354,12 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
} }
if ((mCompiler->mOptions.mAllowHotSwapping) && (typeInstance->mDefineState < BfTypeDefineState_Defined)) if ((mCompiler->mOptions.mAllowHotSwapping) && (typeInstance->mDefineState < BfTypeDefineState_Defined))
{
if (typeInstance->mHotTypeData == NULL)
{
BF_ASSERT(typeInstance->mTypeFailed);
}
else
{ {
auto hotTypeVersion = typeInstance->mHotTypeData->mTypeVersions.back(); auto hotTypeVersion = typeInstance->mHotTypeData->mTypeVersions.back();
@ -4348,6 +4390,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
for (auto member : hotTypeVersion->mMembers) for (auto member : hotTypeVersion->mMembers)
member->mRefCount++; member->mRefCount++;
} }
}
if (typeInstance->mDefineState < BfTypeDefineState_Defined) if (typeInstance->mDefineState < BfTypeDefineState_Defined)
{ {
@ -4962,7 +5005,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
// //
{ {
if (typeInstance->IsSpecializedType()) if ((typeInstance->IsSpecializedType()) || (typeInstance->IsUnspecializedTypeVariation()))
wantsOnDemandMethods = true; wantsOnDemandMethods = true;
else if ((mCompiler->mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_AlwaysInclude) && else if ((mCompiler->mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_AlwaysInclude) &&
(!typeInstance->IsUnspecializedTypeVariation())) (!typeInstance->IsUnspecializedTypeVariation()))
@ -6000,11 +6043,14 @@ BfArrayType* BfModule::CreateArrayType(BfType* resolvedType, int dimensions)
BF_ASSERT(!resolvedType->IsVar()); BF_ASSERT(!resolvedType->IsVar());
BF_ASSERT(!resolvedType->IsIntUnknown()); BF_ASSERT(!resolvedType->IsIntUnknown());
auto arrayTypeDef = mCompiler->GetArrayTypeDef(dimensions);
if (arrayTypeDef == NULL)
return NULL;
auto arrayType = mContext->mArrayTypePool.Get(); auto arrayType = mContext->mArrayTypePool.Get();
delete arrayType->mGenericTypeInfo; delete arrayType->mGenericTypeInfo;
arrayType->mGenericTypeInfo = new BfGenericTypeInfo(); arrayType->mGenericTypeInfo = new BfGenericTypeInfo();
arrayType->mContext = mContext; arrayType->mContext = mContext;
arrayType->mTypeDef = mCompiler->GetArrayTypeDef(dimensions); arrayType->mTypeDef = arrayTypeDef;
arrayType->mDimensions = dimensions; arrayType->mDimensions = dimensions;
arrayType->mGenericTypeInfo->mTypeGenericArguments.clear(); arrayType->mGenericTypeInfo->mTypeGenericArguments.clear();
arrayType->mGenericTypeInfo->mTypeGenericArguments.push_back(resolvedType); arrayType->mGenericTypeInfo->mTypeGenericArguments.push_back(resolvedType);
@ -6450,19 +6496,16 @@ void BfModule::FixIntUnknown(BfTypedValue& lhs, BfTypedValue& rhs)
FixIntUnknown(rhs); FixIntUnknown(rhs);
} }
void BfModule::FixValueActualization(BfTypedValue& typedVal) void BfModule::FixValueActualization(BfTypedValue& typedVal, bool force)
{ {
if (!typedVal.mValue.IsConst()) if (!typedVal.mValue.IsConst())
return; return;
if (mBfIRBuilder->mIgnoreWrites) if ((mBfIRBuilder->mIgnoreWrites) && (!force))
return; return;
auto constant = mBfIRBuilder->GetConstant(typedVal.mValue); auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
if (constant->mConstType == BfConstType_TypeOf) if (!HasUnactializedConstant(constant, mBfIRBuilder))
{ return;
auto constTypeOf = (BfTypeOf_Const*)constant; typedVal.mValue = ConstantToCurrent(constant, mBfIRBuilder, typedVal.mType, false);
AddDependency(constTypeOf->mType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
typedVal.mValue = CreateTypeDataRef(constTypeOf->mType);
}
} }
BfTypeInstance* BfModule::GetPrimitiveStructType(BfTypeCode typeCode) BfTypeInstance* BfModule::GetPrimitiveStructType(BfTypeCode typeCode)
@ -7928,7 +7971,7 @@ bool BfModule::ResolveTypeResult_Validate(BfTypeReference* typeRef, BfType* reso
if ((curGenericTypeInstance->mDependencyMap.mMinDependDepth > 32) && if ((curGenericTypeInstance->mDependencyMap.mMinDependDepth > 32) &&
(genericTypeInstance->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; return false;
} }
@ -9714,7 +9757,14 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
CheckUnspecializedGenericType(genericTypeInst, populateType); CheckUnspecializedGenericType(genericTypeInst, populateType);
resolvedEntry->mValue = genericTypeInst; resolvedEntry->mValue = genericTypeInst;
populateModule->InitType(genericTypeInst, populateType); 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); return ResolveTypeResult(typeRef, genericTypeInst, populateType, resolveFlags);
} }
} }
@ -9731,6 +9781,11 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
} }
typeInst->mTypeDef = typeDef; typeInst->mTypeDef = typeDef;
if (((resolveFlags & BfResolveTypeRefFlag_NoReify) != 0) && (mCompiler->mOptions.mCompileOnDemandKind != BfCompileOnDemandKind_AlwaysInclude))
{
typeInst->mIsReified = false;
}
if (typeInst->mTypeDef->mGenericParamDefs.size() != 0) if (typeInst->mTypeDef->mGenericParamDefs.size() != 0)
{ {
Fail("Generic type arguments expected", typeRef); 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); 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); mContext->mResolvedTypes.RemoveEntry(resolvedEntry);
return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags); return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
@ -9840,7 +9896,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
arrayType->mGenericTypeInfo = new BfGenericTypeInfo(); arrayType->mGenericTypeInfo = new BfGenericTypeInfo();
arrayType->mContext = mContext; arrayType->mContext = mContext;
arrayType->mDimensions = arrayTypeRef->mDimensions; arrayType->mDimensions = arrayTypeRef->mDimensions;
arrayType->mTypeDef = mCompiler->GetArrayTypeDef(arrayType->mDimensions); arrayType->mTypeDef = arrayTypeDef;
arrayType->mGenericTypeInfo->mTypeGenericArguments.push_back(elementType); arrayType->mGenericTypeInfo->mTypeGenericArguments.push_back(elementType);
resolvedEntry->mValue = arrayType; resolvedEntry->mValue = arrayType;
@ -9962,15 +10018,16 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
auto parentTypeInstance = outerTypeInstance; auto parentTypeInstance = outerTypeInstance;
if (parentTypeInstance->IsTypeAlias()) if (parentTypeInstance->IsTypeAlias())
parentTypeInstance = (BfTypeInstance*)GetOuterType(parentTypeInstance)->ToTypeInstance(); parentTypeInstance = (BfTypeInstance*)GetOuterType(parentTypeInstance)->ToTypeInstance();
genericTypeInst->mGenericTypeInfo->mMaxGenericDepth = BF_MAX(genericTypeInst->mGenericTypeInfo->mMaxGenericDepth, parentTypeInstance->mGenericTypeInfo->mMaxGenericDepth);
for (int i = 0; i < startDefGenericParamIdx; i++) for (int i = 0; i < startDefGenericParamIdx; i++)
{ {
genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(parentTypeInstance->mGenericTypeInfo->mGenericParams[i]->AddRef()); genericTypeInst->mGenericTypeInfo->mGenericParams.push_back(parentTypeInstance->mGenericTypeInfo->mGenericParams[i]->AddRef());
genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]); genericTypeInst->mGenericTypeInfo->mTypeGenericArguments.push_back(parentTypeInstance->mGenericTypeInfo->mTypeGenericArguments[i]);
auto typeGenericArg = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[i]; auto typeGenericArg = genericTypeInst->mGenericTypeInfo->mTypeGenericArguments[i];
genericTypeInst->mGenericTypeInfo->mIsUnspecialized |= typeGenericArg->IsGenericParam() || typeGenericArg->IsUnspecializedType(); genericTypeInst->mGenericTypeInfo->mIsUnspecialized |= typeGenericArg->IsGenericParam() || typeGenericArg->IsUnspecializedType();
}
}
}
}
int wantedGenericParams = genericParamCount - startDefGenericParamIdx; int wantedGenericParams = genericParamCount - startDefGenericParamIdx;
int genericArgDiffCount = (int)genericArguments.size() - wantedGenericParams; int genericArgDiffCount = (int)genericArguments.size() - wantedGenericParams;
@ -9989,12 +10046,26 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
for (auto genericArgRef : genericArguments) for (auto genericArgRef : genericArguments)
{ {
auto genericArg = genericArgs[genericParamIdx + startDefGenericParamIdx]; 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->mTypeGenericArguments.push_back(genericArg);
genericTypeInst->mGenericTypeInfo->mTypeGenericArgumentRefs.push_back(genericArgRef); genericTypeInst->mGenericTypeInfo->mTypeGenericArgumentRefs.push_back(genericArgRef);
genericParamIdx++; 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; resolvedEntry->mValue = genericTypeInst;
CheckUnspecializedGenericType(genericTypeInst, populateType); CheckUnspecializedGenericType(genericTypeInst, populateType);
@ -10011,6 +10082,8 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
{ {
BF_ASSERT(BfResolvedTypeSet::Equals(genericTypeInst, typeRef, &lookupCtx)); BF_ASSERT(BfResolvedTypeSet::Equals(genericTypeInst, typeRef, &lookupCtx));
} }
BfLogSysM("Generic type %p typeHash: %8X\n", genericTypeInst, resolvedEntry->mHash);
#endif #endif
BF_ASSERT(BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) == resolvedEntry->mHash); BF_ASSERT(BfResolvedTypeSet::Hash(genericTypeInst, &lookupCtx) == resolvedEntry->mHash);
@ -10145,7 +10218,14 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
CheckUnspecializedGenericType(genericTypeInst, populateType); CheckUnspecializedGenericType(genericTypeInst, populateType);
resolvedEntry->mValue = genericTypeInst; 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); populateModule->InitType(genericTypeInst, populateType);
return ResolveTypeResult(typeRef, genericTypeInst, populateType, resolveFlags); return ResolveTypeResult(typeRef, genericTypeInst, populateType, resolveFlags);
} }
@ -10281,7 +10361,11 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
if ((mCurTypeInstance == NULL) || (!mCurTypeInstance->IsGenericTypeInstance())) if ((mCurTypeInstance == NULL) || (!mCurTypeInstance->IsGenericTypeInstance()))
wantGeneric = false; 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; BfDelegateInfo* delegateInfo = NULL;
BfTypeInstance* delegateType = NULL; BfTypeInstance* delegateType = NULL;
@ -10328,6 +10412,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
Val128 hashContext; Val128 hashContext;
BfTypeDef* typeDef = new BfTypeDef(); BfTypeDef* typeDef = new BfTypeDef();
if (baseDelegateType != NULL)
typeDef->mProject = baseDelegateType->mTypeDef->mProject; typeDef->mProject = baseDelegateType->mTypeDef->mProject;
typeDef->mSystem = mCompiler->mSystem; typeDef->mSystem = mCompiler->mSystem;
typeDef->mName = mSystem->mEmptyAtom; typeDef->mName = mSystem->mEmptyAtom;
@ -10360,8 +10445,11 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
delegateInfo->mDirectAllocNodes.push_back(directTypeRef); delegateInfo->mDirectAllocNodes.push_back(directTypeRef);
if (typeDef->mIsDelegate) if (typeDef->mIsDelegate)
directTypeRef->Init(delegateType); directTypeRef->Init(delegateType);
else if (mCompiler->mFunctionTypeDef == NULL)
failed = true;
else else
directTypeRef->Init(ResolveTypeDef(mCompiler->mFunctionTypeDef)); directTypeRef->Init(ResolveTypeDef(mCompiler->mFunctionTypeDef));
if (!failed)
typeDef->mBaseTypes.push_back(directTypeRef); typeDef->mBaseTypes.push_back(directTypeRef);
directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>(); directTypeRef = BfAstNode::ZeroedAlloc<BfDirectTypeReference>();
@ -11013,7 +11101,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
{ {
SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true); SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true);
auto constraintTypeInst = genericParamInst->mTypeConstraint->ToTypeInstance(); auto constraintTypeInst = genericParamInst->mTypeConstraint->ToTypeInstance();
if ((constraintTypeInst != NULL) && (constraintTypeInst->mTypeDef == mCompiler->mEnumTypeDef)) if ((constraintTypeInst != NULL) && (constraintTypeInst->mTypeDef == mCompiler->mEnumTypeDef) && (explicitCast))
{ {
// Enum->int // Enum->int
if ((explicitCast) && (toType->IsInteger())) 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) 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_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 // 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 // While handling 'var' resolution, we don't want to force a PopulateType reentry
// but we do have enough information for TypeIsSubTypeOf // but we do have enough information for TypeIsSubTypeOf

View file

@ -374,6 +374,50 @@ void BfPrinter::WriteIgnoredNode(BfAstNode* node)
{ {
Visit((BfAstNode*)node); Visit((BfAstNode*)node);
startIdx = node->mSrcStart; 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; int lineEmittedChars = 0;
@ -1803,7 +1847,7 @@ void BfPrinter::Visit(BfDeferStatement* deferStmt)
VisitChild(deferStmt->mDeferToken); VisitChild(deferStmt->mDeferToken);
VisitChild(deferStmt->mColonToken); VisitChild(deferStmt->mColonToken);
VisitChild(deferStmt->mScopeToken); VisitChild(deferStmt->mScopeName);
if (deferStmt->mBind != NULL) if (deferStmt->mBind != NULL)
{ {

View file

@ -3797,6 +3797,8 @@ BfAstNode* BfReducer::DoCreateStatement(BfAstNode* node, CreateStmtFlags createS
} }
else if (nextTokenNode->GetToken() == BfToken_LParen) else if (nextTokenNode->GetToken() == BfToken_LParen)
{ {
mPassInstance->Warn(0, "Syntax deprecated", nextTokenNode);
MEMBER_SET(deferStmt, mOpenParen, nextTokenNode); MEMBER_SET(deferStmt, mOpenParen, nextTokenNode);
mVisitorPos.MoveNext(); mVisitorPos.MoveNext();
@ -9264,9 +9266,9 @@ bool BfReducer::ParseMethod(BfMethodDeclaration* methodDeclaration, SizedArrayIm
bool isFunction = false; bool isFunction = false;
bool isDelegate = 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; 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; isDelegate = true;
if ((!isFunction) && (!isDelegate)) if ((!isFunction) && (!isDelegate))

View file

@ -1686,7 +1686,7 @@ BfType* BfTypeInstance::GetUnionInnerType(bool* wantSplat)
{ {
SetAndRestoreValue<BfFieldDef*> prevTypeRef(mContext->mCurTypeState->mCurFieldDef, fieldDef); SetAndRestoreValue<BfFieldDef*> prevTypeRef(mContext->mCurTypeState->mCurFieldDef, fieldDef);
mModule->PopulateType(checkInnerType); mModule->PopulateType(checkInnerType, checkInnerType->IsValueType() ? BfPopulateType_Data : BfPopulateType_Declaration);
if (checkInnerType->mSize > unionSize) if (checkInnerType->mSize > unionSize)
unionSize = checkInnerType->mSize; unionSize = checkInnerType->mSize;
@ -2194,7 +2194,7 @@ bool BfTypeInstance::WantsGCMarking()
return true; return true;
if ((IsEnum()) && (!IsPayloadEnum())) if ((IsEnum()) && (!IsPayloadEnum()))
return false; return false;
BF_ASSERT(mDefineState >= BfTypeDefineState_Defined); BF_ASSERT((mDefineState >= BfTypeDefineState_Defined) || (mTypeFailed));
return mWantsGCMarking; return mWantsGCMarking;
} }
@ -2674,7 +2674,7 @@ size_t BfTypeVectorHash::operator()(const BfTypeVector& typeVec) const
size_t hash = typeVec.size(); size_t hash = typeVec.size();
BfResolvedTypeSet::LookupContext ctx; BfResolvedTypeSet::LookupContext ctx;
for (auto type : typeVec) 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; 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_PTR 1
#define HASH_VAL_BOXED 2 #define HASH_VAL_BOXED 2
#define HASH_VAL_REF 3 #define HASH_VAL_REF 3
@ -2767,7 +2769,7 @@ BfVariant BfResolvedTypeSet::EvaluateToVariant(LookupContext* ctx, BfExpression*
return variant; 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"); //BP_ZONE("BfResolvedTypeSet::Hash");
@ -2787,13 +2789,13 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
if (type->IsBoxed()) if (type->IsBoxed())
{ {
BfBoxedType* boxedType = (BfBoxedType*)type; 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; return (elemHash << 5) - elemHash;
} }
else if (type->IsArray()) else if (type->IsArray())
{ {
BfArrayType* arrayType = (BfArrayType*)type; 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; return (elemHash << 5) - elemHash;
} }
else if (type->IsDelegateFromTypeRef() || type->IsFunctionFromTypeRef()) else if (type->IsDelegateFromTypeRef() || type->IsFunctionFromTypeRef())
@ -2803,7 +2805,7 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
auto delegateInfo = type->GetDelegateInfo(); 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]; auto methodDef = typeInst->mTypeDef->mMethods[0];
BF_ASSERT(methodDef->mName == "Invoke"); 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++) for (int paramIdx = 0; paramIdx < delegateInfo->mParams.size(); paramIdx++)
{ {
// Parse attributes? // 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; String paramName = methodDef->mParams[paramIdx]->mName;
int nameHash = (int)Hash64(paramName.c_str(), (int)paramName.length()); int nameHash = (int)Hash64(paramName.c_str(), (int)paramName.length());
hashVal = ((hashVal ^ (nameHash)) << 5) - hashVal; hashVal = ((hashVal ^ (nameHash)) << 5) - hashVal;
@ -2852,7 +2854,7 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx]; BfFieldInstance* fieldInstance = &tupleType->mFieldInstances[fieldIdx];
auto fieldType = fieldInstance->mResolvedType; auto fieldType = fieldInstance->mResolvedType;
hashVal = ((hashVal ^ (Hash(fieldType, ctx))) << 5) - hashVal; hashVal = ((hashVal ^ (Hash(fieldType, ctx, BfHashFlag_None, hashSeed))) << 5) - hashVal;
BfFieldDef* fieldDef = NULL; BfFieldDef* fieldDef = NULL;
if (tupleType->mTypeDef != NULL) if (tupleType->mTypeDef != NULL)
fieldDef = fieldInstance->GetFieldDef(); fieldDef = fieldInstance->GetFieldDef();
@ -2874,7 +2876,7 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
{ {
BfTypeInstance* genericType = (BfTypeInstance*)type; BfTypeInstance* genericType = (BfTypeInstance*)type;
for (auto genericArg : genericType->mGenericTypeInfo->mTypeGenericArguments) 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; return hashVal;
} }
@ -2886,7 +2888,7 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
else if (type->IsPointer()) else if (type->IsPointer())
{ {
BfPointerType* pointerType = (BfPointerType*) type; 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; return (elemHash << 5) - elemHash;
} }
else if (type->IsGenericParam()) else if (type->IsGenericParam())
@ -2897,30 +2899,30 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
else if (type->IsRef()) else if (type->IsRef())
{ {
auto refType = (BfRefType*)type; 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; return (elemHash << 5) - elemHash;
} }
else if (type->IsModifiedTypeType()) else if (type->IsModifiedTypeType())
{ {
auto modifiedTypeType = (BfModifiedTypeType*)type; 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; return (elemHash << 5) - elemHash;
} }
else if (type->IsConcreteInterfaceType()) else if (type->IsConcreteInterfaceType())
{ {
auto concreteInterfaceType = (BfConcreteInterfaceType*)type; 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; return (elemHash << 5) - elemHash;
} }
else if (type->IsSizedArray()) else if (type->IsSizedArray())
{ {
auto sizedArray = (BfSizedArrayType*)type; 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; int hashVal = (elemHash << 5) - elemHash;
if (type->IsUnknownSizedArrayType()) if (type->IsUnknownSizedArrayType())
{ {
auto unknownSizedArray = (BfUnknownSizedArrayType*)type; auto unknownSizedArray = (BfUnknownSizedArrayType*)type;
int elemHash = Hash(unknownSizedArray->mElementCountSource, ctx); int elemHash = Hash(unknownSizedArray->mElementCountSource, ctx, BfHashFlag_None, hashSeed);
hashVal = ((hashVal ^ elemHash) << 5) - hashVal; hashVal = ((hashVal ^ elemHash) << 5) - hashVal;
} }
else else
@ -2940,7 +2942,7 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
{ {
BfConstExprValueType* constExprValueType = (BfConstExprValueType*)type; BfConstExprValueType* constExprValueType = (BfConstExprValueType*)type;
int hashVal = ((int)constExprValueType->mValue.mTypeCode << 17) ^ (constExprValueType->mValue.mInt32 << 3) ^ HASH_CONSTTYPE; 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; return hashVal;
} }
else else
@ -2950,21 +2952,29 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef)
return 0; 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)) if (auto elementedTypeRef = BfNodeDynCast<BfElementedTypeRef>(typeRef))
{ {
HashGenericArguments(elementedTypeRef->mElementType, ctx, hashVal); HashGenericArguments(elementedTypeRef->mElementType, ctx, hashVal, hashSeed);
} }
else if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef)) else if (auto qualifiedTypeRef = BfNodeDynCast<BfQualifiedTypeReference>(typeRef))
{ {
HashGenericArguments(qualifiedTypeRef->mLeft, ctx, hashVal); HashGenericArguments(qualifiedTypeRef->mLeft, ctx, hashVal, hashSeed);
} }
if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef)) if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
{ {
for (auto genericArg : genericTypeRef->mGenericArguments) 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()); 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; bool isHeadType = typeRef == ctx->mRootTypeRef;
@ -2990,7 +3000,7 @@ int BfResolvedTypeSet::DirectHash(BfTypeReference* typeRef, LookupContext* ctx,
ctx->mFailed = true; ctx->mFailed = true;
return 0; return 0;
} }
return Hash(resolvedType, ctx); return Hash(resolvedType, ctx, BfHashFlag_None, hashSeed);
} }
BfTypeDef* BfResolvedTypeSet::FindRootCommonOuterType(BfTypeDef* outerType, LookupContext* ctx, BfTypeInstance*& outOuterTypeInstance) BfTypeDef* BfResolvedTypeSet::FindRootCommonOuterType(BfTypeDef* outerType, LookupContext* ctx, BfTypeInstance*& outOuterTypeInstance)
@ -3020,7 +3030,7 @@ BfTypeDef* BfResolvedTypeSet::FindRootCommonOuterType(BfTypeDef* outerType, Look
return commonOuterType; 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) && if ((typeRef == ctx->mRootTypeRef) && (ctx->mRootTypeDef != NULL) &&
((typeRef->IsNamedTypeReference()) || (BfNodeIsA<BfDirectTypeDefReference>(typeRef)))) ((typeRef->IsNamedTypeReference()) || (BfNodeIsA<BfDirectTypeDefReference>(typeRef))))
@ -3073,7 +3083,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size(); int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size();
for (int i = 0; i < numParentGenericParams; i++) 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()) 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)) if (auto genericInstTypeRef = BfNodeDynCastExact<BfGenericInstanceTypeRef>(typeRef))
{ {
@ -3124,7 +3136,9 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
ctx->mFailed = true; ctx->mFailed = true;
return 0; 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; auto parentTypeInstance = checkTypeInstance;
int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size(); int numParentGenericParams = (int)commonOuterType->mGenericParamDefs.size();
for (int i = 0; i < numParentGenericParams; i++) 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; return hashVal;
} }
@ -3171,7 +3185,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
for (int fieldIdx = 0; fieldIdx < (int)tupleTypeRef->mFieldTypes.size(); fieldIdx++) for (int fieldIdx = 0; fieldIdx < (int)tupleTypeRef->mFieldTypes.size(); fieldIdx++)
{ {
BfTypeReference* fieldType = tupleTypeRef->mFieldTypes[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; int nameHash = 0;
BfIdentifierNode* fieldName = NULL; BfIdentifierNode* fieldName = NULL;
@ -3197,7 +3211,7 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
{ {
if ((arrayType->mDimensions == 1) && (arrayType->mParams.size() != 0)) 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 elemHash = rawElemHash ^ HASH_SIZED_ARRAY;
int hashVal = (elemHash << 5) - elemHash; 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); BfTypedValue typedVal = constResolver.Resolve(sizeExpr, NULL, BfConstResolveFlag_ArrayInitSize);
if (typedVal.mKind == BfTypedValueKind_GenericConstValue) 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; hashVal = ((hashVal ^ elemHash) << 5) - hashVal;
return 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; return (elemHash << 5) - elemHash;
} }
} }
else if (auto pointerType = BfNodeDynCastExact<BfPointerTypeRef>(typeRef)) 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; return (elemHash << 5) - elemHash;
} }
else if (auto nullableType = BfNodeDynCastExact<BfNullableTypeRef>(typeRef)) 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; ctx->mRootTypeDef = ctx->mModule->mCompiler->mNullableTypeDef;
int hashVal = ctx->mModule->mCompiler->mNullableTypeDef->mHash; 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; return hashVal;
} }
else if (auto refType = BfNodeDynCastExact<BfRefTypeRef>(typeRef)) 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) else if (refType->mRefToken->GetToken() == BfToken_Mut)
refKind = BfRefType::RefKind_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; return (elemHash << 5) - elemHash;
} }
else else
@ -3356,7 +3370,9 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
ctx->mFailed = true; ctx->mFailed = true;
return 0; 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)) else if (auto varType = BfNodeDynCastExact<BfVarTypeReference>(typeRef))
{ {
@ -3379,26 +3395,26 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
if (ctx->mRootTypeRef != retTypeTypeRef) if (ctx->mRootTypeRef != retTypeTypeRef)
{ {
auto type = ctx->mModule->ResolveTypeRef(retTypeTypeRef, BfPopulateType_Identity, ctx->mResolveFlags); 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; return (elemHash << 5) - elemHash;
} }
else if (auto resolvedTypeRef = BfNodeDynCastExact<BfResolvedTypeReference>(typeRef)) 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)) 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 // 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)) else if (auto delegateTypeRef = BfNodeDynCastExact<BfDelegateTypeRef>(typeRef))
{ {
int hashVal = HASH_DELEGATE; int hashVal = HASH_DELEGATE;
if (delegateTypeRef->mReturnType != NULL) 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 else
ctx->mFailed = true; 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; hashVal = ((hashVal ^ (HashNode(param->mNameNode))) << 5) - hashVal;
isFirstParam = true; isFirstParam = true;
} }
@ -3508,7 +3524,9 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
return 0; 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)) 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); result = EvaluateToVariant(ctx, constExprTypeRef->mConstExpr, resultType);
if ((resultType != NULL) && (resultType->IsGenericParam())) if ((resultType != NULL) && (resultType->IsGenericParam()))
return Hash(resultType, ctx); {
int hashVal = Hash(resultType, ctx, BfHashFlag_None, hashSeed);
hashSeed = 0;
return hashVal;
}
} }
if (resultType == NULL) 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; 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; return hashVal;
} }
else if (auto dotTypeRef = BfNodeDynCastExact<BfDotTypeReference>(typeRef)) else if (auto dotTypeRef = BfNodeDynCastExact<BfDotTypeReference>(typeRef))
@ -3544,6 +3566,14 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
return 0; 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 // 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) 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 HasBeenReferenced() { return mDefineState != BfTypeDefineState_Undefined; }
virtual bool HasTypeFailed() { return false; } virtual bool HasTypeFailed() { return false; }
virtual bool IsDataIncomplete() { return mDefineState == BfTypeDefineState_Undefined; } virtual bool IsDataIncomplete() { return mDefineState == BfTypeDefineState_Undefined; }
virtual bool IsFinishingType() { return false; }
virtual bool IsIncomplete() { return mDefineState < BfTypeDefineState_Defined; } virtual bool IsIncomplete() { return mDefineState < BfTypeDefineState_Defined; }
virtual bool IsDeleting() { return ((mRebuildFlags & (BfTypeRebuildFlag_Deleted | BfTypeRebuildFlag_DeleteQueued)) != 0); } virtual bool IsDeleting() { return ((mRebuildFlags & (BfTypeRebuildFlag_Deleted | BfTypeRebuildFlag_DeleteQueued)) != 0); }
virtual bool IsDeclared() { return mDefineState >= BfTypeDefineState_Declared; } virtual bool IsDeclared() { return mDefineState >= BfTypeDefineState_Declared; }
@ -1774,6 +1775,7 @@ public:
bool mInitializedGenericParams; bool mInitializedGenericParams;
bool mFinishedGenericParams; bool mFinishedGenericParams;
Array<BfProject*> mProjectsReferenced; // Generic methods that only refer to these projects don't need a specialized extension Array<BfProject*> mProjectsReferenced; // Generic methods that only refer to these projects don't need a specialized extension
int32 mMaxGenericDepth;
public: public:
BfGenericTypeInfo() BfGenericTypeInfo()
@ -1785,6 +1787,7 @@ public:
mValidatedGenericConstraints = false; mValidatedGenericConstraints = false;
mInitializedGenericParams = false; mInitializedGenericParams = false;
mFinishedGenericParams = false; mFinishedGenericParams = false;
mMaxGenericDepth = -1;
} }
~BfGenericTypeInfo(); ~BfGenericTypeInfo();
@ -1955,6 +1958,7 @@ public:
virtual bool IsReified() override { return mIsReified; } virtual bool IsReified() override { return mIsReified; }
virtual bool NeedsExplicitAlignment() override { return !IsSizeAligned() || mIsPacked; } virtual bool NeedsExplicitAlignment() override { return !IsSizeAligned() || mIsPacked; }
virtual bool IsDataIncomplete() override { return ((mTypeIncomplete) || (mBaseTypeMayBeIncomplete)) && (!mNeedsMethodProcessing); } virtual bool IsDataIncomplete() override { return ((mTypeIncomplete) || (mBaseTypeMayBeIncomplete)) && (!mNeedsMethodProcessing); }
virtual bool IsFinishingType() override { return mIsFinishingType; }
virtual bool IsIncomplete() override { return (mTypeIncomplete) || (mBaseTypeMayBeIncomplete); } virtual bool IsIncomplete() override { return (mTypeIncomplete) || (mBaseTypeMayBeIncomplete); }
virtual bool IsSplattable() override { BF_ASSERT((mInstSize >= 0) || (!IsComposite())); return mIsSplattable; } virtual bool IsSplattable() override { BF_ASSERT((mInstSize >= 0) || (!IsComposite())); return mIsSplattable; }
virtual int GetSplatCount() override; virtual int GetSplatCount() override;
@ -2525,10 +2529,12 @@ public:
static BfVariant EvaluateToVariant(LookupContext* ctx, BfExpression* expr, BfType*& outType); 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* lhsTypeGenericArguments, BfTypeReference* rhs, LookupContext* ctx, int& genericParamOffset);
static bool GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* typeGenericArguments, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx); static bool GenericTypeEquals(BfTypeInstance* lhsGenericType, BfTypeVector* typeGenericArguments, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx);
static void HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hash); static void HashGenericArguments(BfTypeReference* typeRef, LookupContext* ctx, int& hash, int hashSeed);
static int Hash(BfType* type, LookupContext* ctx, bool allowRef = false); static int DoHash(BfType* type, LookupContext* ctx, bool allowRef, int hashSeed);
static int DirectHash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags = BfHashFlag_None); static int Hash(BfType* type, LookupContext* ctx, bool allowRef = false, int hashSeed = 0);
static int Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHashFlags flags = BfHashFlag_None); 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, BfType* rhs, LookupContext* ctx);
static bool Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* ctx); static bool Equals(BfType* lhs, BfTypeReference* rhs, LookupContext* ctx);
static bool Equals(BfType* lhs, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx); static bool Equals(BfType* lhs, BfTypeReference* rhs, BfTypeDef* rhsTypeDef, LookupContext* ctx);

View file

@ -1,5 +1,6 @@
#include "BfSourceClassifier.h" #include "BfSourceClassifier.h"
#include "BfParser.h" #include "BfParser.h"
#include "BeefySysLib/util/BeefPerf.h"
USING_NS_BF; USING_NS_BF;
@ -421,14 +422,22 @@ void BfSourceClassifier::Visit(BfTokenNode* tokenNode)
void BfSourceClassifier::Visit(BfInvocationExpression* invocationExpr) void BfSourceClassifier::Visit(BfInvocationExpression* invocationExpr)
{ {
BfElementVisitor::Visit(invocationExpr); //BfElementVisitor::Visit(invocationExpr);
Visit(invocationExpr->ToBase());
//BP_ZONE("BfSourceClassifier BfInvocationExpression");
BfAstNode* target = invocationExpr->mTarget; BfAstNode* target = invocationExpr->mTarget;
if (target == NULL) if (target == NULL)
return; return;
VisitChild(invocationExpr->mOpenParen);
VisitChild(invocationExpr->mCloseParen);
VisitChild(invocationExpr->mGenericArgs);
if (auto scopedTarget = BfNodeDynCast<BfScopedInvocationTarget>(target)) if (auto scopedTarget = BfNodeDynCast<BfScopedInvocationTarget>(target))
{ {
VisitChild(target);
target = scopedTarget->mTarget; target = scopedTarget->mTarget;
VisitChild(scopedTarget->mScopeName); VisitChild(scopedTarget->mScopeName);
} }
@ -438,10 +447,12 @@ void BfSourceClassifier::Visit(BfInvocationExpression* invocationExpr)
{ {
VisitChild(qualifiedName->mLeft); VisitChild(qualifiedName->mLeft);
VisitChild(qualifiedName->mDot); VisitChild(qualifiedName->mDot);
VisitChild(qualifiedName->mRight);
identifier = qualifiedName->mRight; identifier = qualifiedName->mRight;
} }
else if ((identifier = BfNodeDynCast<BfIdentifierNode>(target))) else if ((identifier = BfNodeDynCast<BfIdentifierNode>(target)))
{ {
VisitChild(target);
// Leave as BfAttributedIdentifierNode if that's the case // Leave as BfAttributedIdentifierNode if that's the case
identifier = target; identifier = target;
} }
@ -449,14 +460,20 @@ void BfSourceClassifier::Visit(BfInvocationExpression* invocationExpr)
{ {
VisitChild(qualifiedName->mLeft); VisitChild(qualifiedName->mLeft);
VisitChild(qualifiedName->mDot); VisitChild(qualifiedName->mDot);
VisitChild(qualifiedName->mRight);
identifier = qualifiedName->mRight; identifier = qualifiedName->mRight;
} }
else if (auto memberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(target)) else if (auto memberRefExpr = BfNodeDynCast<BfMemberReferenceExpression>(target))
{ {
VisitChild(memberRefExpr->mTarget); VisitChild(memberRefExpr->mTarget);
VisitChild(memberRefExpr->mDotToken); VisitChild(memberRefExpr->mDotToken);
VisitChild(memberRefExpr->mMemberName);
identifier = memberRefExpr->mMemberName; identifier = memberRefExpr->mMemberName;
} }
else
{
VisitChild(target);
}
if (identifier != NULL) if (identifier != NULL)
{ {
@ -469,20 +486,25 @@ void BfSourceClassifier::Visit(BfInvocationExpression* invocationExpr)
if (identifier != NULL) if (identifier != NULL)
SetElementType(identifier, BfSourceElementType_Method); SetElementType(identifier, BfSourceElementType_Method);
} }
for (auto& val : invocationExpr->mArguments)
VisitChild(val);
for (auto& val : invocationExpr->mCommas)
VisitChild(val);
} }
void BfSourceClassifier::Visit(BfIndexerExpression* indexerExpr) void BfSourceClassifier::Visit(BfIndexerExpression* indexerExpr)
{ {
BfElementVisitor::Visit(indexerExpr); //BfElementVisitor::Visit(indexerExpr);
Visit(indexerExpr->ToBase());
VisitChild(indexerExpr->mTarget); VisitChild(indexerExpr->mTarget);
VisitChild(indexerExpr->mOpenBracket); VisitChild(indexerExpr->mOpenBracket);
for (int i = 0; i < (int) indexerExpr->mArguments.size(); i++)
{ for (auto& val : indexerExpr->mArguments)
if (i > 0) VisitChild(val);
VisitChild(indexerExpr->mCommas[i - 1]); for (auto& val : indexerExpr->mCommas)
VisitChild(indexerExpr->mArguments[i]); VisitChild(val);
}
VisitChild(indexerExpr->mCloseBracket); VisitChild(indexerExpr->mCloseBracket);
} }
@ -523,6 +545,8 @@ void BfSourceClassifier::Visit(BfMethodDeclaration* methodDeclaration)
if (!IsInterestedInMember(methodDeclaration)) if (!IsInterestedInMember(methodDeclaration))
return; return;
//BP_ZONE("BfSourceClassifier BfMethodDeclaration");
SetAndRestoreValue<BfAstNode*> prevMember(mCurMember, methodDeclaration); SetAndRestoreValue<BfAstNode*> prevMember(mCurMember, methodDeclaration);
BfElementVisitor::Visit(methodDeclaration); BfElementVisitor::Visit(methodDeclaration);

View file

@ -1654,7 +1654,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
if (isConst) if (isConst)
{ {
BfConstResolver constResolver(this); BfConstResolver constResolver(this);
initValue = constResolver.Resolve(varDecl->mInitializer, resolvedType, BfConstResolveFlag_RemapFromStringId); initValue = constResolver.Resolve(varDecl->mInitializer, resolvedType, BfConstResolveFlag_ActualizeValues);
if (!initValue) if (!initValue)
initValue = GetDefaultTypedValue(resolvedType); initValue = GetDefaultTypedValue(resolvedType);
} }
@ -3934,15 +3934,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt)
bool allowProtected = allowPrivate || TypeIsSubTypeOf(mCurTypeInstance, checkTypeInst); bool allowProtected = allowPrivate || TypeIsSubTypeOf(mCurTypeInstance, checkTypeInst);
while (checkTypeInst != NULL) while (checkTypeInst != NULL)
{ {
auto checkTypeDef = checkTypeInst->mTypeDef; auto dtorMethodDef = checkTypeInst->mTypeDef->GetMethodByName("~this");
checkTypeDef->PopulateMemberSets();
BfMemberSetEntry* entry = NULL;
BfMethodDef* dtorMethodDef = NULL;
checkTypeDef->mMethodSet.TryGetWith(String("~this"), &entry);
if (entry != NULL)
dtorMethodDef = (BfMethodDef*)entry->mMemberDef;
if (dtorMethodDef) if (dtorMethodDef)
{ {
if (!CheckProtection(dtorMethodDef->mProtection, checkTypeInst->mTypeDef, allowProtected, allowPrivate)) if (!CheckProtection(dtorMethodDef->mProtection, checkTypeInst->mTypeDef, allowProtected, allowPrivate))
@ -6734,6 +6726,12 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
if ((scope == mCurMethodState->mCurScope) && (scope->mCloseNode == NULL)) if ((scope == mCurMethodState->mCurScope) && (scope->mCloseNode == NULL))
{ {
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); Warn(0, "This defer will immediately execute. Consider specifying a wider scope target such as 'defer::'", deferStmt->mDeferToken);
} }

View file

@ -833,12 +833,26 @@ int BfTypeDef::GetSelfGenericParamCount()
BfMethodDef* BfTypeDef::GetMethodByName(const StringImpl& name, int paramCount) BfMethodDef* BfTypeDef::GetMethodByName(const StringImpl& name, int paramCount)
{ {
for (auto method : mMethods) PopulateMemberSets();
{ BfMemberSetEntry* entry = NULL;
if ((name == method->mName) && ((paramCount == -1) || (paramCount == (int)method->mParams.size()))) if (!mMethodSet.TryGetWith(name, &entry))
return method;
}
return NULL; return NULL;
BfMethodDef* bestMethodDef = NULL;
auto methodDef = (BfMethodDef*)entry->mMemberDef;
while (methodDef != NULL)
{
if (((paramCount == -1) || (paramCount == (int)methodDef->mParams.size())))
{
if ((bestMethodDef == NULL) ||
((bestMethodDef->mDeclaringType->IsExtension()) && (!methodDef->mDeclaringType->IsExtension())))
bestMethodDef = methodDef;
}
methodDef = methodDef->mNextWithSameName;
}
return bestMethodDef;
} }
BfFieldDef* BfTypeDef::GetFieldByName(const StringImpl& name) BfFieldDef* BfTypeDef::GetFieldByName(const StringImpl& name)
@ -2586,6 +2600,13 @@ void BfSystem::RemoveTypeDef(BfTypeDef* typeDef)
mTypeDefs.Remove(typeDef); mTypeDefs.Remove(typeDef);
AutoCrit autoCrit(mDataLock); 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 // This will get properly handled in UntrackName when we process the mTypeDefDeleteQueue, but this
// mAtomUpdateIdx increment will trigger lookup changes in BfContext::VerifyTypeLookups // mAtomUpdateIdx increment will trigger lookup changes in BfContext::VerifyTypeLookups
if (typeDef->mName != mEmptyAtom) if (typeDef->mName != mEmptyAtom)
@ -2797,6 +2818,7 @@ void BfSystem::InjectNewRevision(BfTypeDef* typeDef)
typeDef->mNextRevision = NULL; typeDef->mNextRevision = NULL;
typeDef->mDefState = BfTypeDef::DefState_Defined; typeDef->mDefState = BfTypeDef::DefState_Defined;
typeDef->mForceUseNextRevision = false;
VerifyTypeDef(typeDef); VerifyTypeDef(typeDef);
} }

View file

@ -1006,6 +1006,7 @@ public:
bool mIsNextRevision; bool mIsNextRevision;
bool mInDeleteQueue; bool mInDeleteQueue;
bool mHasEmitMembers; bool mHasEmitMembers;
bool mForceUseNextRevision;
public: public:
BfTypeDef() BfTypeDef()
@ -1048,6 +1049,7 @@ public:
mIsNextRevision = false; mIsNextRevision = false;
mInDeleteQueue = false; mInDeleteQueue = false;
mHasEmitMembers = false; mHasEmitMembers = false;
mForceUseNextRevision = false;
mDupDetectedRevision = -1; mDupDetectedRevision = -1;
mNestDepth = 0; mNestDepth = 0;
mOuterType = NULL; 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) 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; auto ceAttrAddr = CeMalloc(customAttribute->mType->mSize) - mMemory.mVals;
BfIRValue ceAttrVal = module->mBfIRBuilder->CreateConstAggCE(module->mBfIRBuilder->MapType(customAttribute->mType, BfIRPopulateType_Identity), ceAttrAddr); BfIRValue ceAttrVal = module->mBfIRBuilder->CreateConstAggCE(module->mBfIRBuilder->MapType(customAttribute->mType, BfIRPopulateType_Identity), ceAttrAddr);
BfTypedValue ceAttrTypedValue(ceAttrVal, customAttribute->mType); BfTypedValue ceAttrTypedValue(ceAttrVal, customAttribute->mType);
@ -5408,6 +5408,15 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
mCeMachine->PrepareFunction(callEntry.mFunction, NULL); 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; callEntry.mBindRevision = mCeMachine->mMethodBindRevision;
} }
@ -6255,6 +6264,9 @@ CeMachine::~CeMachine()
auto _RemoveFunctionInfo = [&](CeFunctionInfo* functionInfo) auto _RemoveFunctionInfo = [&](CeFunctionInfo* functionInfo)
{ {
if (functionInfo->mMethodInstance != NULL)
functionInfo->mMethodInstance->mInCEMachine = false;
if (functionInfo->mCeFunction != NULL) if (functionInfo->mCeFunction != NULL)
{ {
// We don't need to actually unmap it at this point // 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")) if (globalVar->mName.StartsWith("__bfStrObj"))
{ {
int stringId = atoi(globalVar->mName.c_str() + 10); 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); auto ptr = data.mData.GrowUninitialized(ceModule->mSystem->mPtrSize);
int64 addr64 = stringAddr; int64 addr64 = stringAddr;
memcpy(ptr, &addr64, ceModule->mSystem->mPtrSize); memcpy(ptr, &addr64, ceModule->mSystem->mPtrSize);
@ -6933,7 +6958,6 @@ CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance, BfIRValue f
ceFunction->mIsVarReturn = methodInstance->mReturnType->IsVar(); ceFunction->mIsVarReturn = methodInstance->mReturnType->IsVar();
ceFunction->mCeFunctionInfo = ceFunctionInfo; ceFunction->mCeFunctionInfo = ceFunctionInfo;
ceFunction->mMethodInstance = methodInstance; ceFunction->mMethodInstance = methodInstance;
ceFunctionInfo->mMethodInstance = methodInstance; ceFunctionInfo->mMethodInstance = methodInstance;
ceFunctionInfo->mCeFunction = ceFunction; ceFunctionInfo->mCeFunction = ceFunction;
MapFunctionId(ceFunction); MapFunctionId(ceFunction);

View file

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

View file

@ -82,17 +82,14 @@ static size_t WriteMemoryCallback(void* contents, size_t size, size_t nmemb, voi
void NetRequest::Cleanup() void NetRequest::Cleanup()
{ {
if (mCURLMulti != NULL) if (mCURLMulti != NULL)
{
curl_multi_remove_handle(mCURLMulti, mCURL); curl_multi_remove_handle(mCURLMulti, mCURL);
}
if (mCURL != NULL) if (mCURL != NULL)
curl_easy_cleanup(mCURL); curl_easy_cleanup(mCURL);
if (mCURLMulti != NULL) if (mCURLMulti != NULL)
{
curl_multi_cleanup(mCURLMulti); curl_multi_cleanup(mCURLMulti);
}
mCURL = NULL;
mCURLMulti = NULL;
} }
void NetRequest::DoTransfer() void NetRequest::DoTransfer()
@ -105,7 +102,10 @@ void NetRequest::DoTransfer()
// return; // return;
// } // }
BfLogDbg("NetManager starting get on %s\n", mURL.c_str()); long response_code = 0;
for (int pass = 0; pass < 3; pass++)
{
BfLogDbg("NetManager starting get on %s Pass:%d\n", mURL.c_str(), pass);
mNetManager->mDebugManager->OutputRawMessage(StrFormat("msgLo Getting '%s'\n", mURL.c_str())); mNetManager->mDebugManager->OutputRawMessage(StrFormat("msgLo Getting '%s'\n", mURL.c_str()));
mOutTempPath = mOutPath + "__partial"; mOutTempPath = mOutPath + "__partial";
@ -155,16 +155,23 @@ void NetRequest::DoTransfer()
} }
} }
// if (result != CURLE_OK) // if (result != CURLE_OK)
// { // {
// mFailed = true; // mFailed = true;
// return; // return;
// } // }
long response_code = 0; response_code = 0;
curl_easy_getinfo(mCURL, CURLINFO_RESPONSE_CODE, &response_code); curl_easy_getinfo(mCURL, CURLINFO_RESPONSE_CODE, &response_code);
mNetManager->mDebugManager->OutputRawMessage(StrFormat("msgLo Result for '%s': %d\n", mURL.c_str(), response_code)); mNetManager->mDebugManager->OutputRawMessage(StrFormat("msgLo Result for '%s': %d\n", mURL.c_str(), response_code));
if ((response_code == 0) || (response_code == 200) || (response_code == 404))
break;
Cleanup();
// Try again!
}
if (response_code == 200) if (response_code == 200)
{ {
curl_off_t downloadSize = 0; 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 enum MethodAErr
{ {
ErrorA, ErrorA,
@ -168,6 +183,13 @@ namespace Tests
Test.Assert(ca.mC == 345); Test.Assert(ca.mC == 345);
Test.Assert(ca.GetValC() == 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;"); Compiler.Mixin("int val = 99;");
Test.Assert(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 extension TClassA<T> where T : IGetExVal
{ {
public T mTVal; public T mTVal;
@ -226,6 +252,26 @@ namespace Tests
ClassE ce = scope .(); ClassE ce = scope .();
Test.Assert(ce.mD == 1); Test.Assert(ce.mD == 1);
Test.Assert(ce.mE == 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] [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] [Test]
public static void TestBasics() public static void TestBasics()
{ {

View file

@ -239,6 +239,32 @@ namespace Tests
switch (methodIdx) switch (methodIdx)
{ {
case 0: 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 }; StructA sa = .() { mA = 1, mB = 2 };
Test.Assert(methodInfo.Name == "StaticMethodA"); Test.Assert(methodInfo.Name == "StaticMethodA");
@ -291,7 +317,7 @@ namespace Tests
let attrC = methodInfo.GetCustomAttribute<AttrCAttribute>().Get(); let attrC = methodInfo.GetCustomAttribute<AttrCAttribute>().Get();
Test.Assert(attrC.mA == 71); Test.Assert(attrC.mA == 71);
Test.Assert(attrC.mB == 72); Test.Assert(attrC.mB == 72);
case 1: case 5:
Test.Assert(methodInfo.Name == "StaticMethodB"); Test.Assert(methodInfo.Name == "StaticMethodB");
var fieldA = typeInfo.GetField("mA").Value; var fieldA = typeInfo.GetField("mA").Value;
@ -337,33 +363,6 @@ namespace Tests
res.Dispose(); res.Dispose();
fieldSAV.Dispose(); fieldSAV.Dispose();
fieldSStrV.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: case 6:
Test.FatalError(); // Shouldn't have any more Test.FatalError(); // Shouldn't have any more
} }
@ -445,6 +444,8 @@ namespace Tests
switch (methodIdx) switch (methodIdx)
{ {
case 0: case 0:
Test.Assert(methodInfo.Name == "__BfCtor");
case 1:
Test.Assert(methodInfo.Name == "GetA"); Test.Assert(methodInfo.Name == "GetA");
var result = methodInfo.Invoke(sa, 34).Get(); var result = methodInfo.Invoke(sa, 34).Get();
@ -464,7 +465,7 @@ namespace Tests
result = methodInfo.Invoke(.Create(&sa), .Create(34)); result = methodInfo.Invoke(.Create(&sa), .Create(34));
Test.Assert(result.Get<int32>() == 1234); Test.Assert(result.Get<int32>() == 1234);
result.Dispose(); result.Dispose();
case 1: case 2:
Test.Assert(methodInfo.Name == "GetB"); Test.Assert(methodInfo.Name == "GetB");
var result = methodInfo.Invoke(sa, 34).Get(); var result = methodInfo.Invoke(sa, 34).Get();
@ -489,16 +490,15 @@ namespace Tests
Test.Assert(sa.mB == 91); Test.Assert(sa.mB == 91);
result.Dispose(); result.Dispose();
case 2:
Test.Assert(methodInfo.Name == "MethodA0");
case 3: case 3:
Test.Assert(methodInfo.Name == "MethodA1"); Test.Assert(methodInfo.Name == "MethodA0");
case 4: case 4:
Test.Assert(methodInfo.Name == "__BfCtor"); Test.Assert(methodInfo.Name == "MethodA1");
case 5: case 5:
Test.Assert(methodInfo.Name == "__Equals"); Test.Assert(methodInfo.Name == "__Equals");
case 6: case 6:
Test.Assert(methodInfo.Name == "__StrictEquals"); Test.Assert(methodInfo.Name == "__StrictEquals");
default: default:
Test.FatalError(); // Shouldn't have any more 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); expressionFlags = (DwEvalExpressionFlags)(expressionFlags & ~DwEvalExpressionFlag_AllowCalls);
} }
if ((expressionFlags & DwEvalExpressionFlag_RawStr) != 0)
{
formatInfo.mRawString = true;
}
auto dbgModule = GetCallStackDbgModule(callStackIdx); auto dbgModule = GetCallStackDbgModule(callStackIdx);
auto dbgSubprogram = GetCallStackSubprogram(callStackIdx); auto dbgSubprogram = GetCallStackSubprogram(callStackIdx);
DbgCompileUnit* dbgCompileUnit = NULL; DbgCompileUnit* dbgCompileUnit = NULL;